1

我的数据库有两张表,一张是城市的距离矩阵,另一张是城市。我的第一个结构是这样的:

  • 城市
    • 用户界面
    • 姓名
    • 纬度
    • 经度

  • 距离
    • FromCityID
    • 到城市ID
    • 距离长度

UUID是CITY表的主键,FromCityID引用ToCityIDCITY作为外键,都是DISTANCE表的复合主键,因为两个城市之间的距离应该是唯一的。

但后来意识到我不想使用UUID和自动增量作为主键,因为我从 XML 上传这个数据库中的数据,其中包含城市和距离。由于距离可能不仅包括当前 XML 中提到的那些城市,还包括数据库中任何先前存储的城市。

我需要一个跨数据库和 XML 的 ID 系统。纬度/经度似乎是最好的选择,所以我将表格更改为:

  • 城市
    • 姓名
    • 纬度
    • 经度

  • 距离
    • FromCityIDLatitude
    • FromCityID经度
    • ToCityIDLatitude
    • ToCityID经度
    • 距离长度

Latitude并且Longitude是 CITY 表的复合主键;FromCityIDLatitude//引用CITY作为外键FromCityIDLongitude,所有四列都是DISTANCE表的复合主键ToCityIDLatitudeToCityIDLongitude

但是使用 4 列作为主键是一个糟糕的设计。在这种情况下,最好的事情是什么?

4

3 回答 3

3

我不同意这种说法:

但是使用 4 列作为主键是一个糟糕的设计。

一个糟糕的设计是一种没有按照您的需要做的设计,或者一种允许数据库中出现不一致的设计。在您的情况下,只要我们做出一个假设,我认为四列主键没有问题。也就是说,您对该表的主要访问路径将使用主键中的每一列。如果是这种情况,那很好;我会将整个表放入唯一索引,并对键的四列设置单独的唯一约束。

四列索引的问题是当您尝试通过第四个叶子访问表时。您可能根本不会使用索引。如果有必要在第四片叶子上定期进行索引查找,则必须添加另一个索引等。最终可能会得到一个可笑的过度索引表。

绕过它的方法是错开装载。不要将 XML 数据直接加载到主数据库表中。将它们加载到辅助表中并运行一个进程以查看该城市是否已存在。如果是,则不要添加它。如果没有,则生成一个新的代理键并执行 CROSS JOIN 以将所有新记录添加到 DISTANCE。

于 2012-11-03T11:12:11.563 回答
1

不要忘记桌子的“物理”设计。对于距离矩阵,考虑使用索引组织表 (IOT),并压缩列。

请参阅 AskTom 上类似问题(关于距离表)的讨论:

http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:239614547000#52902724002052

于 2012-11-03T11:26:09.740 回答
0

要回答您在标题中提出的问题,

在数据库中组织主键的更好方法是什么?

盲键,无论是整数还是通用唯一标识符,几乎总是作为键更好。他们永远不需要改变。数据元素可能会或可能不会改变。

在您的特定情况下,城市的纬度和经度不太可能改变。但是,如果您收到一个城市的纬度/经度校正,您现在必须在两个表中进行校正。

于 2012-11-03T14:34:37.547 回答