我是我们公司唯一的 DBA,在这个行业相对较新(现在有 2.5 年的经验)。开发人员和我目前正在讨论如何为正在开发的新软件正确设计数据库。他们在模块中开发他们的应用程序,并认为每个模块都有一个私有状态表是最好的,我认为最好有一个表来保存所有内部生成的状态(然后可能还有额外的表来赋予这些状态一些意义)。下面的示例代码是用 postgresql 编写的,因为这是我们使用的。
我的方法:
CREATE TABLE status (
status_id SERIAL PRIMARY KEY,
status_code VARCHAR(3) UNIQUE NOT NULL, -- short description
status_description VARCHAR(50) UNIQUE NOT NULL -- long description
);
CREATE TABLE member_status (
status_id INT PRIMARY KEY REFERENCES status (status_id)
);
他们的做法:
CREATE TABLE member_status (
status_id SERIAL PRIMARY KEY,
status_code VARCHAR(3) UNIQUE NOT NULL, -- short description
status_description VARCHAR(50) UNIQUE NOT NULL -- long description
);
-- rinse and repeat for every object that may need a status
他们只看到我的方法有“问题”(尚未明确说明),虽然我没有看到他们的方法有问题,但我确实认为这不是最好的设计。
任何设计更好的输入以及为什么会受到赞赏。
当您想要维护状态表的参照完整性时,您的方法会出现主要问题。
假设你有一个成员表:
现在,如果您想强制引用完整性以确保每个成员都具有有效状态,则不能。这是因为只有一部分状态行适用于成员。因此,可以为成员分配 a
purchase_order_status
,并且 RI 仍将通过。编辑2
在评论中,您澄清了在您的解决方案中成员将对单
member_status
列表具有 RI。这表明您的设计可能会拥有大量单列表,只是为了控制参照完整性。现在,无论何时添加新状态,都需要将其添加到 2 个表中。master_status
你的桌子还有另一个问题。status_code
是独特的。这意味着purchase_order
andsales_order
不能使用相同的代码。这似乎是一个不必要的苛刻限制。但是,删除唯一约束可能会在类别内复制代码。因此,您可能会考虑的下一件事是添加
status_type
并在类型和代码中强制执行唯一约束。因此,您的 status_type 试图通过人为地将主表拆分为多个表来解决根本问题。基本上问题归结为:您试图将多个不同的数据集合并到一个表中,因为它们的某些列重叠是相似的。
Joe Celko 撰写了一篇关于SQL 中的查找表的相当深入的文章。
编辑再三考虑,也许您的方法不太像“一个真正的查找表”,因为您确实承认需要在需要更多详细信息的地方使用其他表。然而,RI 问题仍然存在。