每当我设计一个数据库时,我总是在想是否有最佳的方式来命名我的数据库中的项目。我经常问自己以下问题:
- 表名应该是复数吗?
- 列名应该是单数吗?
- 我应该给表或列加前缀吗?
- 在命名项目时是否应该使用任何大小写?
是否有任何推荐的指南来命名数据库中的项目?
每当我设计一个数据库时,我总是在想是否有最佳的方式来命名我的数据库中的项目。我经常问自己以下问题:
是否有任何推荐的指南来命名数据库中的项目?
我建议查看微软的SQL Server示例数据库:https://github.com/Microsoft/sql-server-samples/releases/tag/adventureworks
AdventureWorks示例使用非常清晰和一致的命名约定,使用模式名称来组织数据库对象。
晚了一些,但简要回答如下:
详细说明:
(1) 您必须做的事情。 有很少的事情是每次都必须以某种方式完成的,但有一些。
(2) 您应该做的事情。
(3) 需要考虑的事情。
CustomerID
是 Customer
表的主键还是其他表中的外键。这只是一个小问题。为什么要使用像 c
这样的差命名呢?CustomerID = Customer.ID
很清楚,因为你可以看到你正在将一个外键与一个主键连接;它不是多余的,因为两边是两个不同的东西。在我看来,单字符命名是很糟糕的做法。 - Dave Cousineau好的,既然我们要发表意见:
我认为表名应该是复数形式。表格是实体的集合(一张表),每行代表一个单独的实体,表格则代表这个集合。因此,我会称一个Person实体的表为People(或Persons,随意取决于您)。
对于那些希望在查询中看到单数“实体名称”的人,我会使用表别名来实现:
SELECT person.Name
FROM People person
有点像LINQ的"from person in people select person.Name"。
至于2、3和4,我同意@Lars的观点。
我在一个带有三个数据库管理员的数据库支持团队中工作,我们考虑的选项是:
我们为表使用单数名称。表通常以系统名称(或其首字母缩写)为前缀。如果系统很复杂,则可以更改前缀以逻辑地将表组合在一起(例如reg_customer、reg_booking和regadmin_limits)。
对于字段,我们期望字段名称包括表的前缀/首字母缩写(即cust_address1),我们还倾向于使用一组标准后缀(_id表示主键,_cd表示“代码”,_nm表示“名称”,_nb表示“号码”,_dt表示“日期”)。
外键字段的名称应与主键字段相同。
例如:
SELECT cust_nm, cust_add1, booking_dt
FROM reg_customer
INNER JOIN reg_booking
ON reg_customer.cust_id = reg_booking.cust_id
在开发新项目时,我建议您列出所有首选的实体名称、前缀和缩略词,并将该文档提供给您的开发人员。然后,当他们决定创建一个新表时,可以参考该文档,而不是“猜测”该表和字段应该被称为什么。
好的,那就是我的$0.02。
Person p;
对象代表 1 条记录,而 List<Person> lp;
集合则是选择了 0 条或多条记录。 - MikeTeeVee我也赞成采用 ISO/IEC 11179 风格的命名约定,但需要注意它们是指导方针而非强制性规定。
参见维基百科上的 数据元素名称:
“表是实体的集合,并遵循集合命名准则。理想情况下,使用集体名称,例如:人事部门。复数形式也是正确的,例如:员工。不正确的名称包括:Employee、tblEmployee 和 EmployeeTable。”
当然,规则都有例外。例如,一个始终只有一行的表可能更适合使用单数名称,例如配置表。而且一致性非常重要:请核查您所在的商店是否有命名约定,如果有,请遵循;如果您不喜欢它,请提出商业案例以便更改,而不是单枪匹马地行动。
我们的偏好:
表名应该是复数吗?
从逻辑上看,将其视为一个集合的论点是有道理的,但您永远不知道表中会包含多少项(0、1或多个)。复数规则会使命名变得不必要地复杂。例如:1个房子,2个房子,老鼠 vs 老鼠,人 vs 人们等等,甚至我们还没有考虑其他语言。
Update person set property = 'value'
将作用于表中的每个人。
Select * from person where person.name = 'Greg'
返回一组person行/结果集。
列名应该是单数吗?
通常是,除非您违反了规范化规则。
我应该在表或列前加前缀吗?
大多数情况下是平台偏好。我们倾向于使用表名前缀来命名列。我们不添加表前缀,但是我们会添加视图(v_)和存储过程(sp_或f_(函数))的前缀。这有助于那些想尝试更新视图中实际计算字段的v_person.age(无论如何都无法进行更新)的人们。
这也是避免关键字冲突的好方法(delivery.from会出现问题,但delivery_from不会)。
这确实使代码更冗长,但通常有助于可读性。
bob = new person()
bob.person_name = 'Bob'
bob.person_dob = '1958-12-21'
... 非常易读和明确。但是,这可能会失控:
customer.customer_customer_type_id
表示customer和customer_type表之间的关系,并指示customer_type表上的主键(customer_type_id)。如果您在调试查询时看到“customer_customer_type_id”,则可以立即知道它来自哪个表(customer表)。
或者,当customer_type和customer_category之间存在M-M关系时(只有某些类型适用于某些类别)
customer_category_customer_type_id
...... 有点长。
在命名项目时,我应该使用任何大小写格式吗?
是的 - 应该使用小写字母,并且要用下划线分隔。这样可以使名称易读且跨平台兼容。结合以上第3点,也更加合理。
但是,大多数情况下这些只是个人偏好。只要保持一致性,在任何需要阅读的人看来都应该是可预测的。
<表名><id>
,例如 PersonID
或 Person_ID
等。因此,如果每个记录都代表一个单独的人而不是一组人,则将表名命名为复数形式就没有意义了。 - Mr. Blond请查看ISO 11179-5: 命名和识别原则,您可以在此处获取:http://metadata-standards.org/11179/#11179-5
我之前在博客里谈到过这个标准,可以在这里查看:ISO-11179命名约定
虽然我知道现在已经有很好的答案回答了这个问题,但我想就第3点提供我的观点,即列名的前缀问题。
所有列应该命名一个在它们所属的表中唯一的前缀。
例如,给定表"customer"和"address",我们可以使用"cust"和"addr"作为前缀。"customer"表中会有"cust_id"、"cust_name"等列。"address"表中会有"addr_id"、"addr_cust_id"(连接到customer的外键)、"addr_street"等列。
当我第一次听到这个标准时,我非常反感;我讨厌这个想法。我无法忍受那么多额外的输入和冗余。现在我已经足够有经验以至于我永远不会回头。
这样做的结果是数据库架构中的所有列都是唯一的。这其中有一个主要的好处,其优势超过了所有反对它的论点(当然,这是我的观点):
你可以搜索整个代码库,并可靠地找到每一行涉及特定列的代码。
来自#1的好处非常巨大。我可以弃用一列并知道在从架构中安全删除该列之前需要更新哪些文件。我可以更改列的含义并知道需要重构哪些代码。或者我只需确定某个部分是否使用了某个列的数据,这很有用。我数不清多少次这已经将一个可能庞大的项目变成了一个简单的项目,也不知道我们在开发工作中节省了多少小时。
另外,相对较小的好处是,只有在进行自连接时才需要使用表别名:
SELECT cust_id, cust_name, addr_street, addr_city, addr_state
FROM customer
INNER JOIN address ON addr_cust_id = cust_id
WHERE cust_name LIKE 'J%';