查找表是否是2019年的良好数据库做法?

R10*_*t-- 6 mysql database oracle

我已经遍历了一些使用大量查找表的表,以引用它们的特定值。对于因查找而只能将5个表扩展为20个以上的表的结构,这使数据库设计极为复杂。我环顾四周,但没有讨论是否使用查找表是一种好习惯。

使用一个查询表,您就可以管理域,允许向域中添加新值,并向devs / dbas显示要遵循的域。但是同时,查找表会使数据库混乱,将不必要的业务逻辑添加到核心数据表中,并使从表中获取信息变得更加复杂。它还要求通过数据库提取执行域查找,这将为使用它的应用程序增加额外的运行时。

如果没有查找表,则数据很容易呈现,在数据库中的混乱程度降低,并使数据库设计更易于查看。但是,这使得查看数据的任何人都无法确定特定列中的值是否与域相关联,并且,如果存在域,则使得该域的管理可以通过应用程序完成。

我的问题是:使用现代标准,查找表是否是实施的好习惯?

Bil*_*win 6

如果你有一个像这样的表:

CREATE TABLE Bugs (
 bug_id INT PRIMARY KEY,
 bug_status VARCHAR(20) DEFAULT 'NEW',
 description TEXT
 ...
);
Run Code Online (Sandbox Code Playgroud)

如果您想知道 的所有有效值是什么,您可以获取当前bug_status正在使用的状态集:

SELECT DISTINCT bug_status FROM Bugs;
Run Code Online (Sandbox Code Playgroud)

但是,您如何知道在查询时表中存在域支持的每种状态的示例?

如果您使用此方法获取允许的错误状态列表,例如填充用户界面的下拉列表,那么您永远无法包含至少一个错误尚未使用的状态。这意味着用户界面将不允许任何人第一次将错误的状态更改为某个值。

这应该是为什么查找表仍然是数据库设计中的合法条目的一个例子。它与“现代标准”无关。我不知道为什么这会改变任何事情。

请注意,如果您不喜欢通过 JOIN 查找表来获取字符串值,则不必这样做。如果您希望将字符串值直接放入主表中,SQL 完全允许这样做。

CREATE TABLE Bugs (
 bug_id INT PRIMARY KEY,
 bug_status VARCHAR(20) DEFAULT 'NEW',
 description TEXT
 ...
 FOREIGN KEY (bug_status) REFERENCES BugStatusTypes (bug_status)
);

CREATE TABLE BugStatusTypes (
 bug_status VARCHAR(20) PRIMARY KEY,
 description TEXT,
 is_active BOOL
);
Run Code Online (Sandbox Code Playgroud)

您可以在字符串列上创建外键,引用查找表的字符串主键。然后主表中的值被限制为允许的值,但您不需要每次想要显示人类可读的值而不是主INT键时都进行联接。

查找表还允许您添加描述性文本来解释域中每个值的用法(我description在上面的示例查找表中显示了一列)。如果您避免使用查找表或使用类型,则无法做到这一点ENUM

同样,我is_active在查找表中添加了一个属性,它允许您“退休”某些值,这样您就知道它们不应该再出现在 UI 中,尽管您可能需要将它们保留在查找中,以便主表中的历史记录还是可以参考值的。这是将额外属性与域中的值关联的示例。除非使用查找表,否则您无法做另一件事。