我有一些想法,有些是我随着时间积累的,但我真的想知道在建模数据库时是什么让事情顺利进行:
答案 0 :(得分:19)
答案 1 :(得分:13)
我还没有提到过一件事:
绝不使用数据库关键字作为对象名称。您不希望每次使用它们时都必须对它们进行限定
如果您在创建时拼错了某些内容,请在发现后立即修复。不要花费数年时间来记住在这个表中UserName真的是Usernmae。当没有太多针对它的代码时,修复起来要容易得多。
永远不要使用隐含连接(逗号语法),始终指定连接。
答案 2 :(得分:11)
将每个人的输入放在一个列表中。
命名标准
数据类型
代码
<强>文档强>
规范化和参照完整性
维护:运行定期脚本以查找
好的
答案 3 :(得分:10)
我的Oracle标准是:
对于SQL Server,唯一的修改是对数据库对象名称使用驼峰大小写(即PartyName而不是party_name)。
查询将倾向于多行写入,每行有一个子句或条件:
SELECT field1, field2, field2
FROM tablename t1
JOIN tablename2 t2 ON t1.id = t2.tablename_id
WHERE t1.field1 = 'blah'
AND t2.field2 = 'foo'
如果SELECT子句足够长,我将每行分割出一个字段。
答案 4 :(得分:9)
答案 5 :(得分:8)
不要忘记定期备份数据库。
答案 6 :(得分:7)
如果数据库适用于特定应用程序,请使用版本表,以便可以根据代码版本(以及其他原因)检查数据库版本。
答案 7 :(得分:7)
请勿在字段名称中使用类型名称。年长的人会记住lpszFieldName的旧MS标准以及随之而来的愚蠢。
使用符合常规语言约定的描述性字段名称。例如“FirstName”而不是“NameFirst”
字段名称中的每个单词都是大写的
没有下划线
请勿使用普通关键字,例如“索引”
不要在ANYTHING前加上对象类型。例如,我们不使用tblCustomers或spCustomersGet。这些不允许良好的分类并提供零值。
使用模式定义数据库的单独区域。如sales.Customers和hr.Employees。这将消除人们使用的大多数前缀。
任何形式的循环都应该被怀疑。通常有一种更好的基于集合的方式。
对复杂的连接使用视图。
尽可能避免复杂的连接。拥有CustomerPhoneNumbers表可能更令人愉快;但老实说,我们真的需要存储多少个电话号码?只需将字段添加到Customers表即可。您的数据库查询速度会更快,而且更容易理解。
如果一个表调用字段“EmployeeId”,那么引用它的EVERY SINGLE TABLE应该使用该名称。它不需要被称为CustomerServiceRepId,因为它位于扩展表中。
几乎所有表都有“s”结尾。例如:客户,订单等。毕竟表中包含许多记录......
使用分析工具评估您的查询,索引和外键关系。甚至那些可能为你生成的。你可能会感到惊讶。
链接支持多对多关系的表在名称中都有链接表。例如,SchoolsGrades。通过表名告诉它它的作用非常容易。
一致。如果你开始遵循惯例的一条路径,除非你愿意重构以前的所有工作,否则不要中途换马。这应该扼杀任何“如果......不会很好”的想法,最终导致混乱和大量的返工。
在输入之前先想想。你真的需要那张桌子,场地,杂物或视图吗?你确定它不在其他地方吗?在添加之前获得一致意见。如果由于某种原因您必须将其取出,请先与您的团队联系。我一直在DBA每天都在不考虑开发人员的情况下做出改变的地方。这不好玩。
答案 8 :(得分:6)
我总是尽量不使用字段名称中的类型 - “sFirstName”,“sLastName”或“iEmployeeID”。虽然它们最初匹配,但如果发生变化,它们将不同步,以后更改这些名称会非常头疼,因为您还必须更改依赖对象。
Intellisense和GUI工具使得找出列的类型变得微不足道,所以我觉得这不是必需的。
答案 9 :(得分:5)
确保每个varchar / nvarchar选择都合适。
确保每个NULLable列选择都是合适的 - 尽可能避免使用NULLable列 - 允许NULL应该是合理的位置。
无论您在此处的建议中使用何种其他规则,我都会在数据库中创建一个可以定期运行的存储过程,以确定您拥有的任何规则或标准的系统运行状况(其中一些是一点点SQL-Server):
在任何由于某种原因无法使用DBMS系统的参照完整性的情况下查找孤立记录(在我的系统中,我有一个进程表和一个测试表 - 所以我的system_health SP查找没有测试的进程,因为我只有单向FK关系)
查找空架构
查找没有主键的表格
查找没有任何索引的表格
查找没有文档的数据库对象(我们使用SQL Server扩展属性将文档放入数据库中 - 此文档可以像列一样精细)。
< / LI>查找特定于系统的问题 - 需要归档的表,不是正常月度或日常处理的异常,具有或不具有默认值的某些常见列名(比如CreateDate)。
寻找非确定性UDF
查找TODO注释,以确保数据库中的代码不会以某种方式具有未经测试或预发布的代码。
所有这一切都可以自动生成,让您全面了解系统健康状况。
答案 10 :(得分:5)
WITH子句确实有助于将查询分解为可管理的部分。
它还有助于提高查询执行计划的效率。
答案 11 :(得分:3)
每个人都以相同的基本格式编写SQL查询(视图,存储过程等)。它确实有助于开发/维护工作。
答案 12 :(得分:3)
一些喜欢和不喜欢。
我的观点是前缀在每个方面都很糟糕。我目前正在使用一个系统,其中表格是前缀,并且表格中的列以2个字母的表格名称首字母缩写为前缀,我每天浪费至少30分钟来处理此数据库,因为首字母缩略词不合逻辑。如果要表示带前缀的内容,请改为使用架构所有者。
如果项目一开始就有一点点暗示文本数据需要支持多语言字符,那么从项目开始使用NVarchar。由于缺乏前瞻性规划和思考而升级大型数据库是一种痛苦和浪费时间。
将where子句中的每个条件拆分到一个新行上以便于阅读(包括在括号和选项卡中的语句中,而不是。)我认为这是我的重要标准。
我曾在一家公司工作,其标准是在执行参数或变量声明时,必须始终将逗号放在行的开头。这显然使它更具可读性,但我发现它是一个完整的噩梦。
答案 13 :(得分:3)
一致的命名标准。让每个人都在同一页面上,使用相同的格式(无论是Camel Case,特定前缀等)都有助于能够准确地维护系统。
答案 14 :(得分:2)
其他一些人(虽然很小)发表评论反对意见......
SQL Server数据库模式对于组织表和存储过程以及控制安全性都很有用。
每个事务表应始终跟踪创建记录的人员和时间,以及在单独的列中更新记录。我看到实施只是简单地使用了“更新日期”,这可能导致未来的审计挑战。
对于具有脱机/同步要求的项目的所有行,请使用GUID作为行标识符。
答案 15 :(得分:2)
良好的数据库设计和规范化。
答案 16 :(得分:2)
除了对3NF或BCNF的规范化(更多关于this question中的规范化),我发现以下内容是有用的:
所以“People”表有一个“PersonID”列。
答案 17 :(得分:2)
表格格式化的SQL。
select a.field1, b.field2
from any_table a
inner join blah b on b.a_id = a.a_id
inner join yet_another y on y.longer_key = b.b_id
where a.field_3 > 7
and b.long_field_name < 2;
部分原因是使用统一长的别名(在这个例子中,这里,a,b和y都是长度为1)。
通过这种格式化,我可以更快地回答常见问题,例如“什么表是'a'的别名?”和“哪些字段将表T连接到查询?”该结构不需要很长时间才能应用或更新,我发现它可以节省大量时间。我们花更多时间阅读代码而不是写代码。
答案 18 :(得分:2)
答案 19 :(得分:1)
13-评估您的查询
这是真的。有时候你没有得到你想要的东西。
对我而言,以明确的西班牙语和使用Upper Camel Case的方式命名表格和字段以及它们的确切内容和(对我们而言)总是有用的,没有空格:
用户名:NombreUsuario
姓氏:ApellidoPaterno
第二姓:ApellidoMaterno
等等
答案 20 :(得分:1)
以“数据库”来表示“SQL产品”,我的回答是“太多了。你可以写一整本关于这个主题的书。”很幸运,有人有。
我们使用Joe Celko的SQL编程风格(ISBN 978-0120887972):“本书是一系列启发式和规则,提示和技巧,可帮助您提高SQL编程风格和熟练程度,以及格式化和编写便携式,可读,可维护的SQL代码。“
这种方法的优点包括:
在实践中,我们确实偏离了“书”的处方,但很少出人意料。
答案 21 :(得分:1)
在MS-SQL中,我总是拥有dbo所拥有的对象,并使用dbo为这些对象添加前缀。
很多次我看到我们的开发人员想知道为什么他们不能称他们无意中拥有的物品。
答案 22 :(得分:1)
记录一切;维基类型文档易于设置,软件是免费的。
确保首先了解界面并设计数据库。大多数情况下,了解您将要使用的数据如何工作然后设计数据库要好得多。最糟糕的数据库设计是因为事情不是在前面发展而发生的。
然后定义您要使用的数据库标准和版本。定义代码元素的标准(视图,函数等),数据库命名;列,表的命名约定;列的类型约定;编码模板。
花时间考虑如何为字段或定制类型定义具有标准数据库类型的类型是一个很好的事情,可以提前进行整理。
作为您的文档的一部分,包括应用程序列表以及应用程序的dos,其中包括您喜欢的首选功能游标,触发器。
定期检讨。
答案 23 :(得分:1)
避免使用愚蠢的缩写惯例,例如积极鼓励像EMP_ID_CONV_FCTR_WTF_LOL_WAK_A_WAK_HU_HU这样的怪物的缩写的综合词典。这条规则启发了我之前见过的一套真实的指导方针。
答案 24 :(得分:1)
答案 25 :(得分:1)
表名与主键名和描述键
相匹配
最近,经过多年的同意,我跳了船,现在每张桌子上都有一个“ID”栏。
是的,我知道,在链接表格时它是不明确的!但是将ProductID链接到ProductID也是如此,所以,为什么要额外输入?
此:
SELECT p.Name, o.Quantity FROM Products p, Orders o WHERE o.ProductID = p.ID
略胜一筹:
SELECT p.Name, o.Quantity FROM Products p, Orders o WHERE o.ProductID = p.ProductID
请注意,两者都需要表或别名前缀。但是,我不仅打字稍微少一点(在具有长描述性名称的数十个表中加倍,并且在数据密集型应用程序中快速加起来),但它也使得更容易知道哪个表是每个连接中的父表,其中,在查询中加入8-10个表时,可以提供相当多的帮助。
答案 26 :(得分:1)
我在这里遵循了很多相同的约定,但我想说一些尚未说过的事情。
无论您是喜欢表格的复数名称还是单数名称,都要保持一致。选择其中一个,但不要同时使用它们。
表中的主键与表的名称相同,后缀为_PK。外键与其对应的主键具有相同的名称,但后缀为_FK。例如,Product表的主键名为Product_PK;在Order表中,相应的外键是Product_FK。我从我的另一位DBA朋友那里挑选了这个习惯,到目前为止,我很喜欢它。
每当我执行INSERT INTO ... SELECT时,我将SELECT部分中的所有列别名以匹配INSERT INTO部分中列的名称,以便更容易维护并查看事物是如何匹配的。
答案 27 :(得分:1)
最重要的标准是:默认情况下没有数据库。我发现太多的开发人员为一个项目抓住了一个数据库,在没有一个项目的情况下生活会更容易(至少还有)。它只是工具箱中的一个工具,并不是每个问题都是钉子。
不恰当地使用数据库会导致域模型贫乏,代码严重不可测试以及不必要的性能问题。
答案 28 :(得分:0)
除了#5之外,我同意你放在那里的所有东西。我经常为表和存储过程使用前缀,因为我们开发的系统有许多不同的功能区域,所以我倾向于在表和sprocs前面加上一个标识符,允许它们根据区域在Management Studio中很好地组合他们属于。
示例:cjso_Users,cjso_Roles,然后你有routing_Users,routing_Roles。这可能听起来像是数据的复制,但实际上两个不同的用户/角色表用于系统的完全独立的功能(cjso将用于基于客户的电子商务应用程序,而路由将代表使用路由的员工和分销商)系统)。
答案 29 :(得分:0)
我喜欢我们的表命名约定:
People Table
PEO_PersonID
PEO_FirstName
...
这有助于使更大的查询更具可读性。和连接更有意义:
Select * -- naughty!
From People
Join Orders on PEO_PersonID = ORD_PersonID
--...
我想的不是命名约定,而是命名的一致性。