“城市”是否应该单独放置一张桌子?

Bor*_*ode 4 join database-design tablespaces database-theory

我有以下客户表:

customer_id - int 
company_name - nvarchar
street - nvarchar
city - nvarchar
comments - nvarchar
Run Code Online (Sandbox Code Playgroud)

该应用程序将仅在一个小国家(例如 30 个城市)的部分地区使用。一位朋友告诉我,我应该将 'city' 分隔到不同的表 'Cities' 中,并在客户表中仅使用 city_id。

就我个人而言,我没有看到它有什么好处(除了在客户表上节省一些空间,在这种情况下,对于创建另一个表的成本来说,这对我来说似乎无关紧要)。

他还提到,因为我有重复的列 - city: foo, city: bar, city: foo. (同城客户很少)这不算归一化,是真的吗?

谁是对的?关于这个问题的任何启示?

Jon*_*gel 6

当你进入它——真正进入它时——存储组件化的地址数据是一个极其复杂的问题,因为全球使用的所有不同和不同的系统。

我想,无论你发展需求的灵活性之间进行平衡,并且只存储什么的业务需求来存储。


这里最大的难题是将所有与地址相关的字段移出Customers表——地址本身就是实体。

空间成本在一个非常小的系统中可能无关紧要(也许),但这更多是关于技术债务问题。如果您需要开始添加更多与地址相关的字段,则必须不断向Customers表中添加越来越多的字段。迟早你会意识到这是一个不灵活的设计——如果你需要为一个给定的客户使用多个地址(账单和送货地址是典型的例子),现在你处于一个没有规范化的伤害世界,因为您不能重用现有结构来存储所需的数据。

至少,创建一个新表Addresses,然后address_id从 中引用Customers。如果你最终想走多地址路线,即使只做这一步(而不是坚持当前的设计)也会在以后省去很多麻烦。

Addresses为了简单起见,地址行可以直接放在表中,也可以放在单独的Address_Lines表中以处理多行。(后者通常是首选。)

在那之后,能够以有意义的方式对数据进行切片和切块的一般最低要求是构建规范化CountriesRegions(又名省/地区/等)和Cities表,只有后者作为Addresses表中的字段出现。这让您可以提出业务问题,例如“我们在 X 市销售了多少产品?” 以及“我们在 Y 区销售了多少产品?”。(注意:根据您操作的位置、您拥有的数据以及数据的切片方式,您可能需要在Regions和之间放置第 4 个表Cities。)

如果您需要更细化(“我们在 X 街上向客户销售了多少产品?”),那么您必须开始将地址行本身组件化,这是真正困难的部分。但是,通常情况下,企业不会问这种问题。鉴于我什至没有看到邮政编码字段,我猜这不是您关心的事情。


Chr*_*xon 5

设计不符合第三范式,但不仅仅是因为城市。STREET、CITY 字段在功能上相互依赖(如果您更改城市,街道也可能会更改,反之亦然)。您还可以以不同方式表示相同的街道、城市组合(Foo St, Foo; Foo Street, Foo 等)。

为了规范这一点,您将创建一个新表 ADDRESSES,其中包含街道、城市等,并通过地址 ID 将客户链接到该表。如果这是您需要的,这还允许您列出客户的多个地址(通过链接表)。

这仍然让您决定是否将城市提取到它自己的表中。要完全满足 3NF,您应该创建一个城市表,您是否需要或想要取决于以下问题的答案:

  1. 您是否(或将要)拥有城市的其他属性(例如人口、县/州、显示名称等)?
  2. 您是否正在执行查询以生成可供选择的不同城市的列表(您的评论建议是)

如果第一点是真的,那么你肯定应该创建一个 CITIES 表,否则你最终可能会得到一个拥有不同人口等的城市。如果第二点是真的,那么最好有一个单独的表作为要列出的查询你所有的城市都会更好地扩展——你只需要扫描这个表而不是(几乎肯定更大的)CUSTOMERS 表,然后从中获取不同的城市。