【问题标题】:Storing matrices in a relational database在关系数据库中存储矩阵
【发布时间】:2010-01-26 20:55:07
【问题描述】:

我正在为客户开发一个项目并完成初始数据库设计。该项目将是一个简单的网络应用程序,用于在矩阵图中跟踪流程及其结果,我正在寻找一种将这些存储在关系表中的好方法。

现在我在想我有一个用于例程的通用表,x 和 y 坐标也将映射,并且可能从包含记录“命中”的坐标 ID 的查找表中脱离出来。有人有更好的方法吗?

谢谢!

编辑:

这只是项目的开始,所以到目前为止我的细节还很有限,但我对多个表的主要推理是因为矩阵的大小和通用性将是完全动态的,因此每个矩阵都可能不同,它们将是绑定到用户

我还忘了提到 x/y 值的顺序很重要,这进一步支持了我在为 x y 和值设置多个表之后的推理,因此我强烈假设需要知道每个单独的单元格很重要

示例:

这方面的基本示例(尽管是抽象的)在于有关餐厅的流程。行为是坐下、点菜、查看菜单、点酒、吃饭、付款等。结果是点菜、送酒、送餐、给钱。虽然看起来很简单,但如果考虑到每次发生的事情都不同,就会变得复杂,在外卖或自助餐的情况下也是如此。在看到情况之间的差异时,行动和结果的顺序变得不可或缺

【问题讨论】:

  • 你将如何查询数据?会有任何聚合查询吗?结果是否需要排序...在哪些属性上?在搜索适当的记录时,您将寻找矩阵的哪些属性,即 WHERE 子句是什么?您的查询会始终获取整个矩阵,还是只需要矩阵的一部分?
  • 请向我们提供有关哪种矩阵的更多详细信息。典型的大小,尺寸是否固定,矩阵中存储了什么样的元素。一些示例也可能会有所帮助。
  • 请提供一些例子来说明你的意思,因为这里真的不太清楚你的具体需求是什么。在这一点上,只有一个普遍的答案是可能的。
  • fyi,要存储一个大小为 50,000 x 50,000 但有 4 个数据点的矩阵,您可以采用一种方式进行设置。要存储大小为 100 x 100 但包含一百万个数据点的矩阵,您将以完全不同的方式设置表格。您可能需要支持“任何”矩阵,但您需要大致了解什么是典型的并偏向您的设计以解决该问题,但仍然适用于其他情况。
  • 细节有限与否,你告诉我们的都是不相关的,没有多大意义:你说它是为了“在矩阵图中跟踪过程及其结果”。这意味着什么?为什么你需要一个矩阵呢?什么样的东西会进入矩阵?一个例子可以帮助加载这里。你说“x 和 y 坐标也将映射的例程的通用表”,对吧?这和你的第一个陈述有什么联系?流程和例程应该是同一件事吗? X 和 Y 是什么?它们与您的行和列有什么关系吗?

标签: sql database-design matrix-storage


【解决方案1】:

有很多方法可以做到这一点,我们需要更多信息才能更具体地了解最适合您的方法。但是,这里有两种 SOP 方式:

每个矩阵都有一个单独的表:

CREATE TABLE YourMatrixName(
    RowNo smallint NOT NULL,
    ColNo smallint NOT NULL,
    CellValue varchar](50) NULL,
 CONSTRAINT [PK_Matrices] PRIMARY KEY CLUSTERED 
    ([RowNo] ASC, [ColNo] ASC)
) ON [PRIMARY];
GO

CREATE UNIQUE NONCLUSTERED INDEX IX_YourMatrixName ON dbo.YourMatrixName
    (ColNo, RowNo); 
GO

或者,一张表中的所有矩阵:

CREATE TABLE Matrices(
    MatrixName varchar(24) NOT NULL,
    RowNo smallint NOT NULL,
    ColNo smallint NOT NULL,
    CellValue varchar(50) NULL,
 CONSTRAINT [PK_Matrices] PRIMARY KEY CLUSTERED 
    ([MatrixName] ASC, [RowNo] ASC, [ColNo] ASC)
) ON [PRIMARY];
GO

CREATE UNIQUE NONCLUSTERED INDEX IX_Matrices ON dbo.Matrices
    (ColNo, RowNo); 
GO

这些是标准的范式,几乎所有其他的方式都没有很好地规范化。这些方法的一些优点:

  1. 您不必填写每个单元格,只需填写您正在使用的单元格即可。或者有一个默认值(0 或“”)并跳过这些。
  2. 这很容易成为最灵活的方法,即使在“一体式”模型中,也无需以任何方式将它们限制为相同的大小,并且很容易调整它们的大小。
  3. 您可以轻松查询矩阵的内容,这在更紧凑的存储方法中变得越来越困难。
  4. “命中”或矩阵单元的任何其他方面很容易实现为行中的附加字段。如果您担心额外的空间,请将它们设为 Null,如果您想单独查询/报告这些属性,则将它们编入索引。使用此型号也可以轻松改装此类功能。

主要缺点是数据开销通常很大。许多人认为插入或检索新矩阵也有很高的开销,但实际上有几种记录在案的技术可以使其非常快。

【讨论】:

    【解决方案2】:

    显存,一个很简单的二维矩阵存储如下:

    ABCD
    EFGH
    IJKL
    

    在 ram 中顺序像数组一样

    A,B,C,D,E,F,G,H,I,J,K,L

    元素 x,y 可以在数组偏移处找到

    [y*width+x]
    

    例如,x=2,y=2(从零开始)指的是元素 K。

    [y*width+x]=[2*4+2]=10. 数组元素 10(再次从零开始)= K,所以你很好。

    存储在逗号分隔的列表中可以让您在 nvarchar 字段中放置任意大小的矩阵。这假设您不需要在 SQL 中查询单个单元格,而只需获取整个矩阵并在客户端处理它。

    您的表格可能如下所示:

    tbl_matrices
    ----
    id
    user_id
    matrix nvarchar(max)
    

    【讨论】:

    • 但只有在您确定不需要查询单个单元格时才这样做
    • 这是一种非常不规范的技术。起初它看起来非常灵活,但实际上,您可能想在 SQL 中使用它做的任何事情都变得越来越难以实现。
    • ...因此短语“假设您不需要在 SQL 中查询单个单元格”。如果有问题的矩阵需要由客户端进行数学操作等,并且不需要在 SQL 端进行最严格的查询,那么这种方法效果很好。如果需要对每个矩阵进行归一化,可以使用一次性客户端应用程序轻松完成。此外,CLR UDF 或 sproc 可用于分离这些数据并执行任何必要的操作。
    【解决方案3】:

    你的矩阵是稀疏的吗?如果它是稀疏的,那么每个条目最好只存储一个命中列表,而不是拥有一个大部分为 0 的完整二维表。

    【讨论】:

    • 矩阵将是动态且可编辑的,因此必须具有灵活性
    【解决方案4】:

    我只使用一张表而不是两张表:(x,y,结果)。除此之外,由于所提供的信息有限,很难提供更多建议。

    【讨论】:

    • 这可能是可能的,但我觉得用代表一件事的多个表进行编码会更容易,并且能够轻松地将每个元素联系起来以具有人类可读的表示
    • 我不确定拥有一个随机 ID 号如何使内容更具可读性
    最近更新 更多