【问题标题】:SQL create multiple vs single "statuses tables"SQL 创建多个与单个“状态表”
【发布时间】:2020-03-29 07:52:22
【问题描述】:

在查看了许多数据库设计之后,我仍然不确定什么是最好的方法。 我正在设计一个数据库,其中大多数实体具有不同的状态。例如,我可能有类似

  • 用户状态:活动、非活动、禁用等。
  • 订单状态:打开、关闭、取消;
  • 办公室状态:打开、关闭。

我考虑了两种不同的选择。

1) 为每个实体创建一个“状态”表

    CREATE TABLE UserStatus(
       UserStatusID int,
       Description varchar(255)
    );
    CREATE TABLE OrderStatus(
       OrderStatusID int,
       Description varchar(255)
    );

2) 为所有实体创建一个共享状态表

    CREATE TABLE Status(
       StatusID int,
       Description varchar(255)
    );

如果您能解释哪个选项更好或每个选项的优点,我将不胜感激

【问题讨论】:

  • 第二种反模式有一个名字“一个真正的查找表”,你不应该使用它。您无法阻止为用户分配具有该设计的订单状态
  • 有意思,我发现了这篇相关文章oracle-base.com/articles/misc/one-true-lookup-tables-otlt
  • 它开始出错了,随着系统的发展,它会变得更糟”总结得差不多

标签: sql database-design


【解决方案1】:

还有一个选项 - 为所有具有 EntityID 的实体创建一个共享状态表。 像这样的:

CREATE TABLE dbo.Entity(
    EntityID int NOT NULL
    CONSTRAINT PK_Entity PRIMARY KEY CLUSTERED,
    Name varchar(50) NOT NULL,
    Description varchar(255) NULL,
)

CREATE TABLE dbo.Status(
    EntityID int NOT NULL
    CONSTRAINT FK_Status_Entity 
    FOREIGN KEY(EntityID)   REFERENCES dbo.Entity (EntityID),
    StatusID int NOT NULL,
    Name varchar(50) NOT NULL,
    Description varchar(255) NULL,
 CONSTRAINT PK_Status PRIMARY KEY CLUSTERED (
    EntityID ASC,
    StatusID ASC)
 CONSTRAINT UQ_Status_EntityID_Name UNIQUE NONCLUSTERED (
    EntityID ASC,
    Name ASC)
) 

【讨论】:

    【解决方案2】:

    多个表有一个关键优势:您可以声明正确的外键关系,以确保引用表中的值正确。

    单个表具有不同的优势:您可以将所有状态集中在一个位置。如果您需要将所有状态翻译成不同的语言,这会非常方便。

    在大多数情况下,我认为第一个优势超过了第二个。然而,在某些情况下,第二个可能很重要。

    【讨论】:

    • 第二种情况总是可以通过创建一个对各个查找表执行 UNION 的视图来模拟。
    • @a_horse_with_no_name 。 . .并不真地。 id 不会是唯一的。
    • 如果这很重要,我会简单地使用一个序列来为所有表生成 ID。
    猜你喜欢
    • 1970-01-01
    • 2017-11-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-28
    • 1970-01-01
    • 1970-01-01
    • 2018-07-07
    相关资源
    最近更新 更多