代码之家  ›  专栏  ›  技术社区  ›  mare

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

  •  1
  • mare  · 技术社区  · 14 年前

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

    现在,下一个要求是每个公司都可以有自己的文档、客户ID,因为很明显,当我们添加一个新公司时,他们创建的任何内容的ID都应该从1开始。

    我在想类似的事情,但它需要手工建造所有的领域,但罗伊德。

    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 回复  |  直到 8 年前
        1
  •  1
  •   garik    14 年前

    使用数据库外观模式(视图、存储过程)是一个很好的实践。它们将所有数据库内部(结构)隐藏在其他世界中。我认为,这是另一个安全问题。每个公司都希望对表级别(而不是行级别)上的某些数据进行受限访问。第二点是:性能。最好有多张桌子而不是一张大桌子。

    因此,我认为,最好让每个公司的表格保持原样,并为报告创建一个视图(我认为):

    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
  •   StuartLC    14 年前

    fwiw,意见

    • 建议您在所有表上保留唯一的代理项pk,以确保联接的唯一性(即保留rowid)
    • 正如你所建议的那样,每个公司唯一的文档、客户等“序列”不会是pk。您需要一个单独的计数器模式或类似的模式。您还可以对每个表的(*prettyid,firmid)实施唯一约束。
    • 尽管不是4nf表单,但出于安全和健全的目的,最好在上面标记一个固定的外键。 所有 您的公司特定表(基本原理:系统发出的每个查询都可能希望按FirmID筛选)。这也会给性能带来好处,因为您不必为了进行过滤而重新加入公司的第一个邻居(而FirmID FK需要进入所有索引)。

    高温高压

        3
  •  1
  •   Damir Sudarevic    8 年前

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

    如果您需要为每个客户定制编号序列,可以为此添加一列( documentcustomid )。

    在Oracle、DB2、PostgreSQL中,可以使用一个序列对象——在SQL Server中,必须创建一个自定义序列器,因此, documentSequence table。对表的访问应该通过存储过程来实现

    • 创建序列
    • 下一个谷
    • 当前值
    • 上一个值

    插入新文档时, documentID auto increments,而从Sequencer对象获得的 documentCustomID should be obtained as a next_value

    以下是指向 db2 , oracle. , postgres >strong>to help with the concept.

    唉。

    如果需要为每个客户定制编号序列,则需要一列( DocumentCustomId )可以为此添加。

    在Oracle、DB2、PostgreSQL中,可以使用序列对象——在SQL Server中,必须创建一个自定义序列器,因此 DocumentSequence 表。对表的访问应该通过存储过程来实现

    • 创建序列
    • 下一个山谷
    • 当前值
    • 先期价值

    插入新文档时, DocumentId 自动递增,而 文档自定义 应作为 next_value 从Sequencer对象。

    doc_model_v3

    这里有几个链接可以在 DB2 , Oracle , Postgres 帮助理解这个概念。

        4
  •  0
  •   user240141    14 年前

    您需要适当地设置pk-fk关系来处理表数据。例如,如果一个公司有多个文档(显然一个公司可以),那么在文档表中,您可以将firmID设置为fk,这是公司表的pk。或者最好的学习关系是映射。做一件事,独立地创建所需的表,而不在表之间建立任何关系。假设您有4个,然后创建4个表,即用户、文档、公司和客户。现在再创建一个表来处理任意两个表的关系。例如。 博士和公司。

    创建一个新表docfirmmaptable,其中三列docfirmmapid作为其pk、docid和firmid。只需在插入两个表时注意这一点,就需要在各自的映射表中再插入一个表。另外,在映射表中,您可以根据需要保留两个或多个表的映射。