我的问题与此问题相同: Custom PrimaryKey Generation with autoincrement。 但有点扭曲。
当我构建这个数据库时,我只有一家公司和一组客户,但现在我经营两家公司,拥有不同的客户群。我的第一个想法是建立两个独立的数据库。但如果我对其中一个做出改变,我必须对另一个做同样的事情,我不想这样做。所以我决定通过同一个数据库运行这两家公司。
我有一个名为Customer
的表,它看起来像这样:
ID
是PK,也设置为自动增量。这一切都很好,直到我决定在同一个DB中运行两个公司。在我决定这个之后,我添加了一个名为CompanyID
的列来将该客户附加到一个特定的公司。当我作为公司1的用户登录我的系统时,我的工作就像它应该的那样,我得到compny 1的客户等等。
但是当我向数据库添加新客户时会出现问题。我希望两家公司的客户ID从1开始。但就像现在一样,当我在copmany 1中创建客户时,它获得了客户编号1,当我在公司2中创建新客户时,它会以相同的数字递增,因此它获得客户编号2.这里我希望它是客户编号1.两个增量应根据CompanyID
分开。
第一步可能是将ID
和CompanyID
都添加为PK,但我还应该做些什么来实现这一目标?
另外,如果你对如何解决这个问题有另一种看法,我想知道!
答案 0 :(得分:1)
执行此操作的最佳方法是使用Company表来处理分配自己的主键,并在Company.CompanyID和Customer.CompanyID之间设置外键关系。然后将公司信息存储在Company表中,并将公司客户的数据存储在Customer表中。这是SQL Server等RDBMS的主要用途,它以关系方式存储数据,以便有效地管理数据。
答案 1 :(得分:1)
好的,首先,你肯定需要针对CompanyID和ID定义你的PK,如果你要完成这个任务(否则,当你试图插入公司2的客户1时,你会得到PK冲突,假设公司1已经有客户1。
一旦你有“无间隙”的要求,你就必须自己滚动一些东西,而不是使用SQL Server中的IDENTITY功能,否则你将失去可扩展性。
两个明显的选项是从该表中为下一个ID选择MAX(ID)+ 1(但在这种情况下,您必须在确定此值和执行插入之间保持独占表锁定),或者维护要使用的下一个ID的单独表格(在这种情况下,您将需要针对您正在使用和递增的行的独占行锁定)。例如。你可能有这样的表:
CREATE TABLE CompanyCustomerIDs (
CompanyID int not null,
NextCustomerID int not null,
constraint PK_CompanyCustomerIDs PRIMARY KEY (CompanyID)
)
然后您在Customers表中的插入看起来像:
declare @CustomerID int
begin transaction
update CompanyCustomerIDs WITH (ROWLOCK,HOLDLOCK,XLOCK) set @CustomerID = NextCustomerID = NextCustomerID + 1 where CompanyID = @CompanyID
insert into Customers (CompanyID,CustomerID,/* Other COlumns */)
select @CompanyID,@CustomerID,/* Other columns */
commit
正如我所说,这会对数据库的可扩展性产生影响。