SQL 采用称为域名完整性的概念,这意味着对象的名称具有由其容器指定的范围。
列名必须是唯一的,但只能在包含列的表的上下文中。表名必须是唯一的,但只能在包含表等的模式的上下文中。
当您查询列时,您需要引用您感兴趣的架构、表和列,除非可以推断出其中的一个或多个。编写查询时,您需要直接按名称或使用别名来引用查询中的表,例如 Customer.ID 或来自 Customer C 的 C.ID 等,除非您的查询非常简单以至于它只引用一个桌子。
曾经有一段时间对所有列名的唯一性有技术要求,这适用于旧的 ISAM 数据库和 1960 年代和 70 年代的 COBOL 等语言。这在 1980 年代被无缘无故地拖入了 dBase,并且在关系和对象 DBMS 时代已经成为一种惯例。抵制这种过时的约定。
当 1970 年代和 80 年代从平面文件和网络数据库转向关系数据库时,连接表的想法是新的。因此,有些人选择了这样的约定:如果一列是对另一列的引用(即外键),则可以重复唯一名称。这个概念被称为“自然连接”,很多人仍然提倡这样做。
我不喜欢自然连接,因为它最终要求您抛弃域名完整性的概念,并强制将整个列引用放入列名中。
自然连接的问题在于您要么必须虚伪,要么必须使列名过长且不可读。让我举例说明:Customer 表的主键是 CustomerID 听起来似乎是个好主意。然后在您的 Invoice 表中,您的 Customer 外键也称为 CustomerID。这将是一个自然的加入,到目前为止一切听起来都不错。这是问题所在。如果您的约定是在每个表上都有一个名为 LastUpdatedDate 的列怎么办?那么您是否打算通过 LastUpdatedDate 将每个表连接到每个其他表?当然不是。这是自然连接的荒谬之处。为了避免这种荒谬,您需要将表名作为前缀插入到列名中。但是,如果您的数据库中有多个模式,则不能止步于此。
另一个自然连接失效的地方是当您在相同的两个表之间存在多个关系时。如果您需要在 Invoice 表中对 Employee 的两个引用(例如,Sold By 和 Approved By),则不能将它们都称为 EmployeeID。