数据库设计支持多个客户端

时间:2010-08-06 08:38:51

标签: sql-server sql-server-2008 database-design

如果您正在构建一个包含表格文档,客户端,用户和公司的数据库,那么在公司中您将存储使用该软件的公司,您将如何设计前三个表以支持多个公司存储在其中?因此,在文档中我们想要为所有公司存储文档,当然,我们需要以某种方式告诉他们appart,所以我们需要像FirmID这样的列。我们也可以将它放在客户端和用户中。

现在,下一个要求是每家公司都可以拥有自己的文件,客户ID,因为当我们添加新公司时,他们创建的任何ID都应从1开始。

我在考虑这样的事情,但它需要手动构建所有字段但RowID。

CREATE TABLE [dbo].[ClientTest](
 [RowID] [int] IDENTITY(1,1) NOT NULL,
 [FirmID] [int] NOT NULL,
 [ClientFirmID] [int] NOT NULL,
 [ClientFirmPrettyID] [varchar](10) NOT NULL,
 CONSTRAINT [PK_ClientTest] PRIMARY KEY CLUSTERED 
(
 [RowID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

RowID将在这种情况下自动运行,但它对我们没用,因为对于我们所做的一切,我们需要使用ClientFirmID和ClientFirmPrettyID。有没有办法自动创建这两个?

4 个答案:

答案 0 :(得分:1)

FWIW,意见

  • 建议你在所有牌桌上保留一个独特的代理PK以获得连接(即保留你的RowID)
  • 正如您对“PrettyId”所建议的那样,每个公司的文档,客户等公司独特的“序列”将不是PK。你需要一个单独的计数器模式或类似的。您还可以在每个表上强制执行唯一约束(* PrettyId,FirmId)。
  • 虽然不是4NF格式,但是出于安全和理智的目的,在 ALL 您的公司特定表格上标记一个FirmId外键可能是一个好主意(理由:几乎每个系统发出的查询都将可能想要通过FirmId过滤。这也会带来性能上的好处,因为您不一定需要加入到Firm的第一个邻居才能进行此过滤(而且FirmId FK需要进入所有索引。

HTH

答案 1 :(得分:1)

使用数据库外观模式(视图,存储过程)是一种很好的做法。它们隐藏了来自其他世界的所有数据库内部(结构)。我认为,另一点是安全性。每个公司都希望限制访问表级别的某些数据(不是行级别)。第二点是:表现。有很多桌子比一个大桌子更好。

所以我认为,最好是保留每家公司的表格并创建报告视图(我认为):

CREATE view dbo.Client
    as
    SELECT  ClientId= ClientId, FirmPrettyId = 'first'
    FROM         dbo.FirstCompanyClient 
    UNION ALL 
    SELECT     ClientId = Client_Id, FirmPrettyId = 'second'
    FROM                       dbo.SecondCompanyClient

<强>增加:

alt text http://i34.tinypic.com/2yydonc.jpg

使用触发器或存储过程为某些公司和范围(“客户”或“文档”)生成下一个ID:

UPDATE dbo.zz_IdGenerator 
    SET
        @nextId = NextId,
        NextId = @nextId + 1
    WHERE FirmId = @firmId and Scope = @scope 

    RETURN  @nextId;

<强>更新:

UPDATE dbo.zz_IdGenerator...插入存储过程,并在插入文档或客户端表之前调用它。

alt text http://i35.tinypic.com/dcro9g.jpg

答案 2 :(得分:1)

主键的目的是唯一地标识表中的行,而不是作为某种可能具有某种含义的业务键。

如果您需要为每个客户自定义编号顺序,可以为其添加一列(DocumentCustomId)。

在Oracle,DB2,Postgresql中可以使用序列对象 - 在SQL Server中,您必须创建自定义序列器,因此需要DocumentSequence表。对表的访问应该通过应该实现的存储过程

  • create_sequence
  • next_vale
  • current_value
  • previous_value

插入新文档时,DocumentId自动递增,而DocumentCustomId应从序列发生器对象获取为next_value

doc_model_v3

以下是 DB2 Oracle Postgres 中序列对象的几个链接帮助这个概念。

答案 3 :(得分:0)

您需要适当地设置PK-FK关系来处理表数据。例如,如果一家公司有多个文档(显然是公司可以),那么在表格中您可以将FirmID作为fk,即固定表的PK。或者最好学习的关系是映射。做一件事,创建所需的表independenlty没有表之间的任何关系。假设您有4个表,然后创建4个表,即用户,文档,公司和客户端。现在再创建一个表来处理任何两个表的关系。例如。 文件和公司。

Craete一个新表DocFirmMapTable,其中三列DocFirmMapId作为其PK,DocId,FirmId。只需要在插入两个表时需要注意这一点,您需要在各自的映射表中再插入一个。同样在map表中,您可以根据您的要求保留两个或两个以上表的映射。