主键/外键命名约定
在我们的开发小组中,我们对主键和外键的命名规则有一个激烈的争论。 我们组中基本上有两个学派:
1:
Primary Table (Employee) Primary Key is called ID Foreign table (Event) Foreign key is called EmployeeID
要么
2:
Primary Table (Employee) Primary Key is called EmployeeID Foreign table (Event) Foreign key is called EmployeeID
我不想在任何列中复制表的名称(所以我更喜欢上面的选项1)。 从概念上讲,它与其他语言中的许多推荐实践一致,即在其属性名称中不使用对象的名称。 我认为命名外键EmployeeID
(或者Employee_ID
可能更好)告诉读者它是Employee
Table的ID
列。
其他一些人则更喜欢选项2,其中您指定了以表名为前缀的主键,以便整个数据库中的列名相同。 我明白了这一点,但是现在你不能直观地将主键与外键区分开来。
此外,我认为在列名中包含表名是多余的,因为如果您将表视为实体,将列视为实体的属性或属性,则将其视为Employee
的ID属性,不是EmployeeID
属性。 我不去问我的同事他的PersonAge
或PersonGender
是什么。 我问他年龄是多less。
所以就像我说的那样,这是一场激烈的辩论,我们一直在继续。 我有兴趣得到一些新的观点。
这并不重要。 我从来没有碰到过一个select1和select2有真正区别的系统。
Jeff Atwood在这个话题上有一篇很棒的文章。 基本上,人们辩论和辩论那些他们不能被certificate是错误的话题。 或者从另一个angular度来看,这些只能通过阻挠风格的耐力才能赢得的话题才是最后一个争论的话题。
挑一个,告诉他们把重点放在实际影响你的代码的问题上。
编辑:如果你想获得乐趣,让他们在长度上指定为什么他们的方法是优于recursion表引用。
如果这两个表在两个表中都有相同的名称(约定#2),则可以使用SQL中的USING语法来保存一些键入和一些样板噪声:
SELECT name, address, amount FROM employees JOIN payroll USING (employee_id)
另外一个支持第2号公约的论点是关系模型的devise方式。
每栏的重要性部分通过标注相应域的名称来expression。
我认为这取决于你如何把你的应用程序放在一起。 如果您使用ORM或devise您的表来表示对象,则选项1可能适合您。
我喜欢将数据库编码为自己的图层。 我控制一切,应用程序只是调用存储过程。 具有完整列名的结果集是很好的,特别是当有许多表连接在一起并返回许多列时。 有了这个应用程序,我喜欢选项2.我真的很喜欢看到连接上的列名匹配。 我在旧系统上工作,他们不匹配,这是一场噩梦,
这两个公约都不适用于所有情况,为什么一个公司呢? 使用常识…
例如,对于自引用表,当有多个FK列自引用同一个表的PK时,由于两个FK列不能被命名为相同,所以您必须违反两个“标准”。 EmployeeId PK,SupervisorId FK,MentorId Fk,PartnerId FK,…
我同意他们之间没有多lessselect。 对于我来说,更重要的是任何标准都是“标准”部分。
如果人们开始“做自己的事情”,他们应该被他们的清洁工所打断。 恕我直言 :)
如果您正在查看应用程序代码,而不仅仅是数据库查询,有些事情看起来很清楚:
-
表定义通常直接映射到描述一个对象的类,所以它们应该是单数的。 为了描述一个对象的集合,我通常将“Array”或“List”或“Collection”附加到单数名称上,因为它比使用复数更清楚,不仅表示它是一个集合,而且表示什么样的集合它是。 在该视图中,我将表名称看作不是集合的名称,而是作为集合的对象types的名称。 不写应用程序代码的DBA可能会错过这一点。
-
我处理的数据通常使用“ID”作为非密钥识别的目的。 为了消除关键的“ID”和非关键的“ID”之间的混淆,对于主键名,我们使用“Key”(这就是它是什么,是不是?)前缀表名或缩写表名。 这个前缀(我只保留主键)使得键名是唯一的,这是特别重要的,因为我们使用与数据库列名相同的variables名,而大多数类都有一个父类,父母的关键。 这也是需要确保它不是一个保留的关键字,这是“钥匙”本身。 为了便于保持关键variables名称的一致性,并为进行自然连接的程序提供外键,它们的名称与它们是主键的表中使用的名称相同。 我有不止一次遇到使用自然连接这种方式更好的scheme。 在最后一点,我承认我用过的自引用表有一个问题。 在这种情况下,我会对外键命名规则做一个例外。 例如,我将使用ManagerKey作为Employee表中的外键,以指向该表中的另一条logging。
我喜欢会议#2 – 在研究这个话题,并发布之前发布我自己的问题,我遇到了这样一个问题:
我从包含大量列的表中select*并将其连接到类似地具有大量列的第二个表。 两个表都有一个“id”列作为主键,这意味着我必须明确地挑出每一列(据我所知),以使这两个值在结果中是唯一的,即:
SELECT table1.id AS parent_id, table2.id AS child_id
虽然使用约定#2意味着我将仍然有一些名称相同的结果列,我现在可以指定我需要哪个 id(父或子),如史蒂文Huwigbuild议, USING
语句进一步简化了事情。
我一直使用userId作为一个表上的PK,而用另一个表上的userId作为FK。 认真考虑使用userIdPK和userIdFK作为名字来识别另一个。 这将帮助我在查看表格时快速识别PK和FK,并且在使用PHP / SQL访问数据时,它似乎会清除代码,从而更容易理解。 特别是当别人看我的代码。
我们使用的约定与A非常接近,除了我们以复数forms命名表(即“employees”)并在表名和列名之间使用下划线。 这样做的好处是要引用一个列,它是“employees_id”或“employees.id”,取决于你想要访问它。 如果您需要指定列来自哪个表,“employees.employees_id”绝对是多余的。
我使用约定#2。 我正在使用传统的数据模型,现在我不知道在给定的表中代表什么。 冗长的危害在哪里?
如何命名外键
ROLE_ID
其中angular色是被引用的实体相对于当前表格的angular色。 这解决了recursion引用和多个fks到同一个表的问题。
在许多情况下将与被引用的表名相同。 在这种情况下,您的build议就会变得完全相同。
无论如何,长期的争论是一个坏主意
“在哪里”employee INNER JOIN命令ON order.employee_id = employee.id“是否需要额外的资格?”。
不需要额外的资格,因为我所说的资格已经在那里了。
“业务用户引用订单ID或员工ID的原因是为了提供上下文,但是在数据库层面上,您已经拥有上下文,因为您正在引用该表”。
请问,告诉我,如果这个专栏被命名为“ID”,那么如何“完全按照表格”完成,除非通过完全按照我所说的方式来限定这个ID列的引用?
你有没有考虑以下?
Primary Table (Employee) Primary Key is PK_Employee Foreign table (Event) Foreign key is called FK_Employee