【问题标题】:Basic table design Q基本表设计 Q
【发布时间】:2010-10-10 11:22:54
【问题描述】:

我正在尝试理解这个概念。例如:我有两张表 City 和 Country。

Country
-------
id  
abbreviation   
name   


City
-----
id   
name   
Country (name or id, or both? - This is the question)

要引用特定城市并使其与其所属的国家保持同步,我想这将引用 country.id 作为 FK。这意味着城市表的示例将是:(200, New York, 19) - 其中 19 = 国家表中的美国。但这对查看表格的人没有帮助,因为如果不查看国家/地区表格中的 19 是什么,他不会知道 19 是什么。

所以我想将国家/地区名称也添加到城市表中,使其显示为:(200, New York, USA)。我不需要显示 19,因为 19 对读者没有用,而只是用于连接表格。

那么我的表列 / FK 应该是什么样子,我可以存储在这样的城市表行中(200,纽约,美国),但确保纽约将始终在美国查找中引用美国并保留 19 USA out of city table 的主键是否使表格看起来干净且易于理解?我假设如果引用了这些,明天如果我将 USA 更新为 20,它将在城市表中自行更新,同样,如果我将 USA 重命名为 US,它将在城市表中自行更新?

  • 我的数据库在 MySQL 中

【问题讨论】:

    标签: mysql database schema


    【解决方案1】:

    为什么不使用 ISO 3166 国家代码(2 个字符或 3 个字符)作为国家 ID?这会在城市表中为您留下可识别的代码;您可以映射到国家/地区表中的全名。

    至于查看数据,使用 VIEW 创建一个好看的表:

    CREATE VIEW CityInfo(CityID, CityName, CountryID, CountryName) AS
        SELECT ci.id, ci.name, ci.country, co.name
          FROM City AS ci JOIN Country AS co ON ci.Country = co.id;
    

    【讨论】:

    • 这只是一个例子。我有很多数据,比如社区、州、地区、地方、邮政等,所有这些都需要相互连接,所以我试图理解用于所有这些表的概念,所以 1)表中的数据是有意义的, 2)连接的数量更少,3)数据可以在表之间保持同步(如强制),所以如果我对主查找表进行更改,其他地方的任何名称更改都会更新。
    • 那么你将不得不决定如何处理事情。您正在进入极其复杂的领域,特别是如果您想对不同国家/地区的地址进行分析。您可以创建表以避免连接;请注意,与完全规范化的表相比,您正在为非常复杂的更新操作进行设置。使用完全规范化的表可能会更好 - 如果它们经常更改。如果一旦设置它们基本上是静态的,那么“预加入”版本可能会更好。但您对美国以外地址的分析将是关键因素。
    • 另见:SO 3094126S 929684OSO 310540,仅举三例。
    【解决方案2】:

    如果您需要在数据库中拥有“可用”表,那么您不需要...,因此有人可以使用 select * 等轻松查看有用的内容(或者使手动编写 SQL 更容易)。然后你创建上面的表格,以正常形式,然后创建一个组合表格的视图。

    【讨论】:

    • 输出更多。如果我使用城市查找表进行自动建议,我想显示:美国纽约。这是最终目标。要得到这个,这意味着我必须查找 City,然后查看 19 对国家的引用,在国家表中找到 19 并输出 USA,因此它显示为 New york, USA。 ...但是如果我在城市表中也有国家名称,那么它是一个简单的输出而不会打到两个表。注意:这只是示例。我有数百个这样的查找,我需要创建多个表,因此我试图理解用于所有这些的基本概念。
    • 我想确保如果我确实在城市表中保留国家名称,它仍然与其父国家/地区表相关,因此任何未来的名称或 ID 更改都会反映在它被引用的所有表中。
    • 哈哈,所以您认为简单连接对性能的影响会花费您很多钱,以至于让您的表不正常是值得的?
    【解决方案3】:

    表格不应该被人们查看:某些应用程序应该访问表格,以便以人们可以解析的方式将数据呈现给人们。您希望将 country.id 作为表中的 FK 的原因是,您不会有一百万行的国家名称为“USA”,因为这样就会出现各种问题,例如当您输入错误时会发生什么“美国 A” 登陆其中一个领域?或者,如果您想将用户看到的内容从“USA”更改为“United States”,该怎么办?

    正确的处理方式是按照你最初的建议使用 country.id,然后使用 JOIN 语句来呈现数据,如下所示:

    SELECT city.name, country.name
      FROM city JOIN country ON country.id = city.country
    

    我的语法可能是关闭的,但本质上这就是你想要的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-03-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-10
      • 1970-01-01
      相关资源
      最近更新 更多