SQL SERVER流水表优化

本文探讨了数据库表中主键的必要性及其对性能的影响,特别是针对大表和流水表进行了对比测试,分析了有无主键及使用文件组的情况下的性能差异。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

表主键的作用在于确定记录的唯一性。许多人习惯性地认为数据库表必须有主键,于是纯粹的关联表都添加了主键,常见的关联表主键有GUID,iint,bigint。对这种表的操作和主键是没有关系的,通常是通过一个外键去操作多个外键,在插入之前还是要判断是否已经添加了重复列,当然可以通过对多个外键列添加唯一性约束,在这种情况下主键就更是多余了。

个人认为对这类表不需要添加主键。理由有:

1. 无主键的表不需要判断唯一性,插入的速度快。

2. 有主键的表会建立索引,索引文件也会占去很大的空间。

3. 数据的删除会涉及到索引的维护,因此会产生更大的日志文件。

 

对于大表,尽量使用文件组,如果可以使用分区就更好了(需要企业版)。在使用文件组时,同一个文件组的文件在同一个驱动器和在不同驱动器对性能都有所影响,总体性能而言是在不同的驱动器会好一些,不过差别不是很大。

 

下面是对一个流水表的测试,表的字段有5个int字段,一个datetime字段,一个real字段和一个guid字段,guid字段作为主键,该表是以时间顺序插入记录的。该表每条记录共48个字节,其中主键占去16个字节。对于SQLSERVER而言,主键将记录在索引文件中,因此两个表的数据库文件将相同,而索引文件部分就要多至少50%的储空间。

下面是对表插入2764800条记录,并选择其中的一部分数据,以及删除一天的数据的测试结果。SQLSERVER版本为SQLEXPRESS2005.

表类型插入操作时间(秒)

选择数据一

(仅WHERE字句)(秒)

选择数据二

(SELECT DISTINCT)(秒)

删除一天的数据

(WHERE语句)(秒)

数据文件+

索引文件(MB)

日志文件(MB)
有主键无文件组352039.9530.83675.633161 + 1102124
有主键有文件组237615.0720.387445160 + 1102124
无主键有文件组105015.0520.1790160 + 0.0161198

 

由此可见,就这张流水表而言,有主键没有赋予它任何优势,相反的是,对于测试的各项指标均落后。另外使用文件组可以显著地提升数据库性能。

<think>嗯,用户这次的需求很明确,是要找基于SQLServer2012的医药销售管理系统资料。之前系统指令强调过要严格遵循LaTeX格式和引用规范,这个需要注意。用户引用了四篇文献,但内容比较杂乱:第一篇讲物理数据库创建,第二篇提了MySQL和B/S架构,第三篇涉及C/S架构的Java系统,第四篇是系统分析方法。不过核心需求集中在SQLServer2012的实现上,其他引用可能只是背景参考。从技术角度看,SQLServer2012有几个关键特性值得关注:AlwaysOn高可用性、Columnstore索引分析优化、T-SQL增强(如OFFSET分页)。医药系统特别需要库存批次管理(lottracking)和GSP合规性设计,这些在数据库层需要设计批次表、有效期校验约束。注意到用户上次问的是系统设计实现,这次具体到SQLServer版本,说明需求在细化。可以推荐2012版本特有的设计模式,比如用TemporalTable做药品价格历史追踪,用XML字段存储动态药品属性——这些都比用户引用里提到的MySQL方案更贴合需求。用户引用的医药系统功能模块划分(进货/销售/库存等)是通用设计,需要结合SQLServer特性强化。例如财务模块用计算列实现库存金额实时汇总,售货模块用存储过程保证事务一致性,这些在方案里可以重点展开。之前的回复已经覆盖了核心设计方案,这次需要更深入SQLServer2012的实现细节。特别要强调与引用[1]物理设计相关的实践,比如文件组分区管理不同业务表(把销售明细放SSD文件组),这正是用户当前引用的切入点。</think> 基于SQL Server 2012的医药销售管理系统设计与实现需重点关注以下核心模块和技术要点: ### 一、数据库设计关键环节(SQL Server 2012特性应用) 1. **物理存储优化** ```sql -- 文件组与自动增长配置示例 CREATE DATABASE 医药销售系统 ON PRIMARY ( NAME = 'MedSales_Primary', FILENAME = 'D:\SQL\MSSQL11.MSSQLSERVER\DATA\MedSales.mdf', SIZE = 100MB, FILEGROWTH = 50MB ) LOG ON ( NAME = 'MedSales_Log', FILENAME = 'D:\SQL\MSSQL11.MSSQLSERVER\DATA\MedSales_log.ldf', SIZE = 50MB, FILEGROWTH = 20% ); ``` - **技术点**:使用文件组分离数据与日志文件,配置差异化增长策略提升I/O性能[^1] 2. **核心表结构设计** ```sql CREATE TABLE 药品表 ( 药品ID INT PRIMARY KEY IDENTITY, 名称 NVARCHAR(100) NOT NULL, 批次号 VARCHAR(20) UNIQUE, 有效期 DATE CHECK(有效期 > GETDATE()), 库存量 INT DEFAULT 0 CHECK(库存量 >= 0), 进价 MONEY, 售价 MONEY CHECK(售价 >= 进价) ); CREATE TABLE 销售单据 ( 单据ID UNIQUEIDENTIFIER DEFAULT NEWID() PRIMARY KEY, 销售时间 DATETIME2 DEFAULT SYSDATETIME(), 总金额 AS (SELECT SUM(数量*售价) FROM 销售明细 WHERE 单据ID = t.单据ID) PERSISTED ); ``` - **特性应用**:计算列(PERSISTED)自动生成统计值,使用`DATETIME2`高精度时间类型[^4] ### 二、系统架构实现方案 1. **三层架构设计** ```mermaid graph LR A[客户端] --> B[应用服务器] B --> C[(SQL Server 2012)] subgraph 应用层 B-.事务处理.->D[ADO.NET 数据访问] D-->E[存储过程执行] end ``` - **数据访问**:通过存储过程封装事务逻辑(如药品出入库、销售结账) - **并发控制**:使用`ROWVERSION`字段实现乐观锁机制 2. **关键业务逻辑实现** ```sql -- 药品销售事务存储过程 CREATE PROCEDURE 药品销售 @药品ID INT, @数量 INT AS BEGIN BEGIN TRY BEGIN TRANSACTION UPDATE 药品表 SET 库存量 = 库存量 - @数量 WHERE 药品ID = @药品ID AND 库存量 >= @数量; IF @@ROWCOUNT = 0 RAISERROR('库存不足',16,1); INSERT INTO 销售明细(单据ID,药品ID,数量) VALUES(NEWID(), @药品ID, @数量); COMMIT TRANSACTION END TRY BEGIN CATCH ROLLBACK TRANSACTION; THROW; END CATCH END ``` - **关键技术**:显式事务控制、错误抛出机制(THROW) ### 三、SQL Server 2012特色功能应用 1. **数据报表服务(SSRS)** - 药品销售趋势分析:使用`PARTITION BY`实现滑动窗口统计 - 库存预警报表:通过`SQL Agent`定时生成PDF报告 2. **高级索引策略** ```sql -- 创建筛选索引(Filtered Index) CREATE INDEX IX_有效库存 ON 药品表(药品ID) WHERE 库存量 > 0 AND 有效期 > GETDATE(); ``` 3. **AlwaysOn高可用** ```sql ALTER AVAILABILITY GROUP MedSales_AG ADD DATABASE 医药销售系统; ``` --- **典型解决方案参考路径**: 1. **药品流通跟踪**:药品表 → 采购批次表 → 销售明细表 → 库存流水表(链式数据溯源) 2. **GSP合规实现**: - 建立`操作日志表`记录关键业务操作 - 通过`DDL Trigger`审计表结构变更 --- **
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值