Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 表格设计为;封锁;避免锁定的表格?_Sql Server_Database_Database Design - Fatal编程技术网

Sql server 表格设计为;封锁;避免锁定的表格?

Sql server 表格设计为;封锁;避免锁定的表格?,sql-server,database,database-design,Sql Server,Database,Database Design,我有一个应用程序,其中有一群用户,他们很少看到或与彼此的数据交互,即使数据在同一个表中。实际上,它们95%的时间都可以运行单独的SQL Server数据库。但是我不想为每一个都建立一个单独的数据库,因为这会带来它自己的问题(例如,其他5%的时间) 我如何进行设计,使组之间永远不会(或最小限度地)“锁定”,并且查询速度更快?也就是说,用户之间是“隔离”的,在理想情况下不需要锁定相同的资源(索引、密钥等) 例如,设想一个表来保存“销售订单”: 起初,我在SalesOrderId上只有主键作为标识,但

我有一个应用程序,其中有一群用户,他们很少看到或与彼此的数据交互,即使数据在同一个表中。实际上,它们95%的时间都可以运行单独的SQL Server数据库。但是我不想为每一个都建立一个单独的数据库,因为这会带来它自己的问题(例如,其他5%的时间)

我如何进行设计,使组之间永远不会(或最小限度地)“锁定”,并且查询速度更快?也就是说,用户之间是“隔离”的,在理想情况下不需要锁定相同的资源(索引、密钥等)

例如,设想一个表来保存“销售订单”:

起初,我在SalesOrderId上只有主键作为标识,但现在我经常看到一个插入,它锁定主键,导致另一个组中的用户的插入等待。即使几乎不会有一个查询会扫描整个表,或者由于“另一个组”的记录是否存在而产生任何错误结果。所以这一切看起来都很浪费

我是否应该切换到上面的设计,其中所有键都涉及UserGroupId

同样,想象一下涉及DatePlaced的查询。组A只需要“他们的”记录,所以索引应该是(UserGroupId,dateplace)吗?避免无用地扫描其他用户的销售订单

也就是说,基本上每个主键、外键、索引等都将UserGroupId作为其第一个组件

因此,按顺序(1..many)排列的“项目”表应为:

create table SalesOrderItem(
    GroupId int not null foreign key references UserGroup(UserGroupId),
    SalesOrderId int not null,
    SalesOrderItemId int not null,
    primary key(GroupId, SalesOrderItemId),
    foreign key (GroupId, SalesOrderId) references SalesOrder(UserGroupId, SalesOrderId)
)

希望这是有意义的,谢谢你的帮助

如果插入冲突导致问题,听起来您有不同的问题。另一方面,插入与选择冲突的内容。。。确保聚集索引相同。同时考虑快照隔离,防止选择查询锁定,同时避免脏读取。谢谢本!似乎发生的是我插入了一条记录,该记录触发identity约束以生成一个新的PK值。但这会在insert所包装的事务期间锁定整个表,不幸的是,这可能需要相当长的时间。这会导致“select”语句等待。因此,重点是强制SQLServer只锁定表的“部分”,而不是所有操作的“整个”表。这将大大减少争论。密钥重新设计是否真的做到了这一点是我问题的核心?不,生成标识不会锁定表。还有别的事情。但这里的大问题是,您有一个长期运行的事务。没有长时间运行的事务。很明显,标识不会锁定表,但insert至少会锁定行和索引页。确保对表和所有索引启用了行锁定。考虑快照隔离,因为有很多其他事情在不知道这些东西是什么的情况下是不可能给你更好的帮助的。如果插入冲突导致问题,听起来您有不同的问题。另一方面,插入与选择冲突的内容。。。确保聚集索引相同。同时考虑快照隔离,防止选择查询锁定,同时避免脏读取。谢谢本!似乎发生的是我插入了一条记录,该记录触发identity约束以生成一个新的PK值。但这会在insert所包装的事务期间锁定整个表,不幸的是,这可能需要相当长的时间。这会导致“select”语句等待。因此,重点是强制SQLServer只锁定表的“部分”,而不是所有操作的“整个”表。这将大大减少争论。密钥重新设计是否真的做到了这一点是我问题的核心?不,生成标识不会锁定表。还有别的事情。但这里的大问题是,您有一个长期运行的事务。没有长时间运行的事务。很明显,标识不会锁定表,但insert至少会锁定行和索引页。确保对表和所有索引启用了行锁定。考虑快照隔离,因为有很多其他事情在不知道这些东西是什么的情况下是不可能给你更好的帮助的。
create table SalesOrderItem(
    GroupId int not null foreign key references UserGroup(UserGroupId),
    SalesOrderId int not null,
    SalesOrderItemId int not null,
    primary key(GroupId, SalesOrderItemId),
    foreign key (GroupId, SalesOrderId) references SalesOrder(UserGroupId, SalesOrderId)
)