在SQL表

时间:2016-08-22 20:24:00

标签: sql sql-server

我试图在SQL中用四个独立点(以及[...]这里表示的各种其他属性)来表示一个对象。单表方法可能如下所示:

CREATE TABLE Object (
    Id bigint NOT NULL IDENTITY(1,1) PRIMARY KEY,
    [...]
    Point1X float NOT NULL,
    Point1Y float NOT NULL,
    Point2X float NOT NULL,
    Point2Y float NOT NULL,
    Point3X float NOT NULL,
    Point3Y float NOT NULL,
    Point4X float NOT NULL,
    Point4Y float NOT NULL
)

多表方法可能看起来更像这样:

CREATE TABLE Object (
    Id bigint NOT NULL IDENTITY(1,1) PRIMARY KEY,
    [...]
    Point1 bigint NOT NULL FOREIGN KEY REFERENCES Point(Id),
    Point2 bigint NOT NULL FOREIGN KEY REFERENCES Point(Id),
    Point3 bigint NOT NULL FOREIGN KEY REFERENCES Point(Id),
    Point4 bigint NOT NULL FOREIGN KEY REFERENCES Point(Id)
)

CREATE TABLE Point (
    Id bigint NOT NULL IDENTITY(1,1) PRIMARY KEY,
    XCoord float NOT NULL,
    YCoord float NOT NULL
)

第二种方法看起来更优雅来自OO设计背景,但与此同时,我已经可以看到在我的ORM中更新有问题的对象时如何处理更加困难而且我不会# 39; t喜欢我添加的FK约束的数量。第一个选项看起来非常混乱,这也意味着我将无法在事后添加其他属性(例如,如果我想在六个月内为每个点分配一个Color'时间)。

我还会说有第三个选项,其中Points表维护一个外键引用回Object,这意味着一个对象现在可以有任意数量的点。我不喜欢这个选项。对于项目的当前范围,对象将只有四个点,因此必须在我的应用程序层处理约束,这使得处理ORM内部的关系变得更加困难。

制定这样的设计的正确方法是什么?

编辑:更多细节:

  • 点代表矩形每边的中点 - 想象一个十字形的形状。
  • 了解哪些点彼此相对非常重要 - 因此有一个中心定义,或者有某种排序(例如,point1总是直接来自point3)。
  • 除上述约束外,没有点的排序。
  • 目前我只会查询对象然后绘制他们的分数,而不是针对分数本身运行查询,尽管我可以看到这是将来的要求。
  • 对象不应重叠,但这不是系统中的硬约束。
  • 对象同样不应该共享相同的四个点。由于这些点是浮点数(至少在这个例子中 - 我对数据类型提出了更好的建议)并且最初是从用户输入中获取的(想想画布上的鼠标光标位置)我不认为&# 39;很可能任何两个对象都会共享任何点。

3 个答案:

答案 0 :(得分:0)

这不是一个不寻常的设计决定。

在你的两种方法之间,我更喜欢第二种方法。原因很简单。如果你有四个“东西”,那么“某些东西”听起来就像一个实体。在关系模型中,实体应该有自己的表。

但是,您拒绝我的实际首选选项,即将外键引用返回到原始对象。唯一的问题是强制执行数字约束。您可以通过使用触发器来维持计数并拒绝任何插入第五个点的尝试。我并不满足于使用触发器的需要,但SQL并不总是足以表示我们想要直接表示的所有内容。

答案 1 :(得分:0)

CREATE TABLE Object (
    Id bigint NOT NULL IDENTITY(1,1) PRIMARY KEY,
    [...]
)

CREATE TABLE Point (
    Id bigint NOT NULL IDENTITY(1,1) PRIMARY KEY,
    XCoord float NOT NULL,
    YCoord float NOT NULL
)

CREATE TABLE ObjectPointCrossRef (
    Id bigint NOT NULL IDENTITY(1,1) PRIMARY KEY,
    ,ObjectId bigint NOT NULL
    ,PointId bigint NOT NULL
)

我理解这种结构从应用程序编程的角度来看并不是很好,但就数据的立场和灵活性来说,它可以很好地适应应用程序需求的变化。此外,如果您通常在对象之间共享点,这可能会节省空间,因为多个对象可以引用相同的点...以现在需要5点(五角大楼)为例,不需要编程更改[我知道你说赢了'发生但我只能假设您允许某种矩形....或者可能只为1个对象添加颜色,为“交叉参考”表添加颜色。

答案 2 :(得分:0)

这是更多的意见,说明了对这个问题进行建模的正确方法。

您有3种潜在的设计。我打电话给他们

  1. 单桌
  2. 两桌
  3. 三张桌子(马特答案)。
  4. 在我看来,关键因素是:

    • 是否需要概括对象之间的关系并指向1到N的关系?关系总是1到4?
    • 是否需要使用对象上下文之外的点?比如需要查询给定范围内的所有点?

    如果这两个问题的答案是否/否,那么我将使用解决方案1,并将组合模型留在OO空间中,为OO / DB映射层分配将对象图分解为1行的任务在1表中。是的,列defs看起来不优雅,但一旦桌子到位,一切都应该更容易使用。没有加入。没有FK。没有可能意外创建只有2分的对象。使用此解决方案您也可能获得最佳性能。

    如果对上述任一问题的回答是肯定的,我会选择选项#3,尽管我认为关联表需要另一个字段来指定一个点与对象的关系(即点#1 /#3或点) #2 /#4)。毫无疑问,Matt在撰写答案时并未意识到这一要求。