我们有一个团队为软件开发人员设计表格和关系。在我们的组织中,他们对执行 3NF 规范化非常严格——老实说,鉴于我们组织的规模以及需求或我们的客户如何随时间变化,我同意这一点。只有一个方面我不清楚他们设计决策背后的原因:地址。
虽然这主要集中在美国的地址,但我认为这适用于任何这样做的国家。地址的每一部分在地址表中都有自己的列。例如,以这个粗糙的美国地址为例:
Attn: Jane Doe
485 1/2 N Smith St SW, APT 300B
Chicago, IL 11111-2222
Run Code Online (Sandbox Code Playgroud)
它会像这样在数据库中拆分:
还会有一些其他与农村路线和合同路线相关的专栏。此外,我们的特定应用程序中可能会包含一些国际地址。数据建模人员表示,他们将添加特定于国际地址的列,这将是正常的第 1 行、第 2 行字段。
起初我认为这太过分了。在网上反复搜索是指使用地址行 1、2、3 和可能的 4,然后拆分出城市、地区和邮政编码。我们的新应用程序确实有一个用例,这种粒度是有益的。我们必须验证用户没有创建重复的业务,检查地址是验证之一。我们可以让它与地址行 1 和 2 一起工作,但这会更困难。
至于我们的具体应用,我们需要为企业和个人存储多种地址(物理、邮寄、运输等)。我们可能需要生成可打印的套用信函,但目前尚未讨论该要求。
我们组织中的应用程序需要支持的其他一些东西:
虽然我们的应用程序可能不会做所有其他应用程序正在做的所有事情,但将地址拆分为多个组件是我工作的企业标准。不管我们的应用程序是否会从中受益,我们都被迫这样做。
半相关的 StackOverflow 问题:关闭的好的地址解析器在哪里,但说明解析地址有多么困难。
为了让我更好地理解他们的设计决策,并把这个想法卖给我们的客户……
将街道地址拆分为单独的列解决了哪些问题?
任何实施过此类系统的人都会获得奖励积分,因为他们遇到了问题。
我习惯于在非常安全的环境中工作,因此我将权限设计为非常精细的粒度。我通常做的一件事是明确地为DENY用户提供UPDATE永远不应该更新的列的能力。
例如:
create table dbo.something (
created_by varchar(50) not null,
created_on datetimeoffset not null
);
Run Code Online (Sandbox Code Playgroud)
一旦设置了值,就不应更改这两列。因此,我明确DENY了UPDATE他们的权限。
最近,在一次团队会议上,一位开发人员提出了一个观点,即确保字段永远不会更新的逻辑应该包含在应用程序层而不是数据库层中,以防“他们出于某种原因需要更新值”。对我来说,这听起来像是典型的开发人员心态(我知道,我曾经是其中之一!)
我是我公司的高级架构师,我一直遵循让应用程序运行所需的最少权限的原则。所有权限都会定期审核。
这种情况下的最佳实践是什么?
我正在设计一个数据库,我正在重新考虑我最初的设计决定......
产品类型如下... 型号、零件、替换零件套件和选项。
选项 A(第一个设计):我计划为上述产品类型设置单独的表格。我想说每个表中大约 75% 的字段是相同的。
我将每个产品类型创建为单独的表,因为我需要在它们之间创建关联。例如,一个模型可以有很多选项,一个选项可以有很多模型。一个选项也可以有很多部分,一个部分可以有很多选项……等等……
选项 B:我可以创建一个名为 Product 的表格,而不是单独的表格,其中包含模型、零件、替换零件套件和选项。我可以有一个称为 type 的字段来区分模型、选项等。我认为不利的一面是某些产品类型永远不会使用几个字段(留空)。我猜这就是“非最佳实践”发挥作用的地方。
选项 B 将大大降低数据库设计的复杂性。在提取数据进行查询时,我也不必担心引用一堆表......
是否可以具有如下自定义唯一约束?假设我有两个 colssubset和type,两个字符串(尽管数据类型可能无关紧要)。
如果type是“真”,那么我希望的组合type,并subset是唯一的。否则,没有约束。我在 Debian 上使用 PostgreSQL 8.4。
postgresql index database-design constraint unique-constraint
我正在设计一个以不同语言存储数据的数据库(使用 UTF-8),所以我认为显示查询结果的最佳方式是在查询期间根据用户的语言对其进行排序(因为有多个正确的方法来做到这一点),如下:
SELECT a < b COLLATE "de_DE" FROM test1;
Run Code Online (Sandbox Code Playgroud)
假设这是处理国际数据的正确方法,那么对于数据库本身来说,哪种整理是最好的呢?PostgreSQL 文档说:
C 和 POSIX 排序规则都指定了“传统的 C”行为,其中只有 ASCII 字母“A”到“Z”被视为字母,并且严格按照字符代码字节值进行排序。
我认为这是这种情况下的最佳选择,还是我错了?
(额外的问题:在查询本身中选择排序规则是否太慢?)。
我应该在设计表格时使用varchar(255)或varchar(256)吗?我听说一个字节用于列的长度,或用于存储元数据。
在这一点上它不再重要了吗?
我在互联网上看到了一些帖子,但是它们适用于 Oracle 和 MySQL。
我们有 Microsoft SQL Server 2016 企业版,它如何应用于这种环境?
现在举个例子,如果我告诉我的客户保留例如 255 个字符而不是 256 个字符的文本描述,有什么区别吗?我读到的内容“最大长度为 255 个字符,DBMS 可以选择使用单个字节来指示字段中数据的长度。如果限制为 256 或更大,则需要两个字节。” 这是真的?
database-design sql-server varchar sql-server-2016 enterprise-edition
我想要一种一对多的关系,其中对于每个父母,一个或零个孩子被标记为“最喜欢的”。然而,并不是每个父母都会有孩子。(将家长视为本网站上的问题,将孩子视为答案,将最喜欢的视为已接受的答案。)例如,
TableA
Id INT PRIMARY KEY
TableB
Id INT PRIMARY KEY
Parent INT NOT NULL FOREIGN KEY REFERENCES TableA.Id
Run Code Online (Sandbox Code Playgroud)
在我看来,我可以将以下列添加到 TableA:
FavoriteChild INT NULL FOREIGN KEY REFERENCES TableB.Id
Run Code Online (Sandbox Code Playgroud)
或 TableB 的以下列:
IsFavorite BIT NOT NULL
Run Code Online (Sandbox Code Playgroud)
第一种方法的问题在于它引入了一个可为空的外键,据我所知,它不是规范化形式。第二种方法的问题是需要做更多的工作来确保最多只有一个孩子是最喜欢的。
我应该使用什么样的标准来确定使用哪种方法?或者,还有其他我没有考虑的方法吗?
我正在使用 SQL Server 2012。
normalization foreign-key database-design sql-server relational-theory
为什么在数据库中应用约束?放在代码里不是更灵活吗?
我正在阅读一本关于实现数据库的初学者书籍,所以我作为初学者来问这个问题。假设我设计了一个数据库,包括这个实体模型:
entity type | sub-types
----------------+--------------------------------------------
Person | Employee, Student, ...
Student | Graduate, Undergraduate, ...
Employee | Teacher, Administrator, ...
Run Code Online (Sandbox Code Playgroud)
当前限制:
后来我们决定去掉数字 1:如果有一天学院决定Teacher(Employee子类型)也可以Student,在空闲时间参加课程,改变数据库设计要困难得多,可能有数千、数百万、数十亿,数以万计的条目,而不仅仅是更改代码中的逻辑:只是不允许一个人同时注册为学生和员工的部分。
(这是非常不可能的,但我现在想不出其他任何事情。 显然这是可能的)。
为什么我们在数据库设计而不是代码中关心业务规则?
#1:7 年后的一个笔记,一个真实的例子:
我见过一个政府,因为一个错误,发放的 SSN 被复制了:多人,同一个 SSN。那些设计原始数据库的人肯定犯了没有在数据库中应用这种唯一性约束的错误。(后来原始应用程序中的一个错误?多个应用程序使用共享数据库并且不同意在哪里放置、检查和强制执行约束?...)。
这个错误将继续存在于系统中,之后开发的所有系统都依赖于原始系统的数据库,未来很多年。阅读这里的答案,我学会了在数据库中明智地(而不是盲目地)应用所有约束,尽可能多地应用它们,以尽可能好地表示那里的真实物理世界。
我们可以通过多种方式存储日期和时间信息。存储 DateTime 信息的最佳方法是什么?
使用 DateTime将日期和时间存储在2 个单独的列或一列中?
你能解释为什么这种方法更好吗?
(链接到 MySQL 文档以供参考,问题是一般性的,不是特定于 MySQL)
日期和时间类型:日期和时间
database-design ×10
sql-server ×3
index ×2
postgresql ×2
address ×1
audit ×1
collation ×1
constraint ×1
datetime ×1
foreign-key ×1
permissions ×1
varchar ×1