SQL中的"动态"表?

kas*_*ter 1 .net c# t-sql database-design entity-attribute-value

我目前正在讨论一些关于网站想法的东西 - 我非常想让我的用户创建"Tables"来保存数据,然后允许他们查询这些数据(以比写作更怪异的方式) SQL查询,希望比使用excel更容易).

到目前为止,我的想法是使用几个表在我的数据库中表示它 - 有一个表代表一个表,一个表代表表的列,有一个表代表表中的每一行,最后一个代表值.类似于(PSEUDO SQL)的东西:

CREATE TABLE 'Tables' (
   Id INT NOT NULL PRIMARY KEY,
   NAME VARCHAR(255)
)

CREATE TABLE 'TableColumns' (
   Id INT NOT NULL PRIMARY KEY,
   TableId INT NOT NULL FOREIGN KEY ON 'Tables',
   NAME VARCHAR(255)
)

CREATE TABLE 'TableRows' (
   Id INT NOT NULL PRIMARY KEY,
   TableId INT NOT NULL FOREIGN KEY ON 'Tables',
   RowNumber INT NOT NULL
)

CREATE TABLE 'TableValues' (
   RowId INT NOT NULL PRIMARY KEY,
   ColumnId INT NOT NULL PRIMARY KEY,
   Value VARCHAR(255)
)
Run Code Online (Sandbox Code Playgroud)

(请注意,TableValues表在这里有2个主键字段,它应该代表一个"复合"主键,不要因为我的语法不合法SQL而烦恼太多,它应该只显示这个想法).

我做了一些测试,并能够成功地进行简单的查询(简单的过滤,排序等).我这样做的方法是首先查询TableRows表 - 为了过滤我然后过滤掉列与列表不匹配的行,并且为了排序我根据列的内容(由指定的排序指定)对RowIds进行排序.导致所需顺序的行ID列表,从这里开始只是为了选择所需的内容.

所有这一切都很好,但我从这里开始有点困惑.我想以某种方式能够表示不同的数据类型(这是我真正的主要问题),并且稍后还要研究如何进行连接.

在考虑这一切的同时,我开始怀疑是否有更好的方法来做到这一点.请注意,此处的性能是一个因素,但我不打算支持具有数十万行的虚拟表,每个虚拟表可能大约1000行 - 当然整个系统需要能够处理许多这些.

我知道我总是可以在我的数据库中实际创建表格,在C#中实时创建查询以实现此目的,同样仅使用SQL查询进行查询 - 但是我从来没有让用户"构建"查询数据库的巨大粉丝像这样 - 在我看来好像会导致出现许多错误的路径 - 并且在最坏的情况下最终会允许用户以某种方式杀死数据库.

此外,我的问题变成了如何以一种从C#角度理解的方式处理这个问题.到目前为止,我认为我倾向于使用LINQ然后创建我自己的扩展方法,这些方法将应用所需的功能 - 即扩展IQueryable的ExtensionMethods.

所以我真正喜欢的是关于如何做到这一点的想法,如何调整性能的想法,如何处理表中的单独数据类型的想法(当然将类型存储在表列中,但如何实际存储值,以便我可以通过它进行过滤,排序等等? - 而不只是在我的tablevalues表上添加"TextValue","MoneyValue"等列.最后但并非最不重要的是,希望在这里进行一些很好的讨论 - 我至少认为这是一个有趣的话题.

Den*_*ler 9

出于某种原因,每个人都会在某个时刻遇到这个想法.

看来是对的,它应该有效.

它会.有点.

关于TheDailyWTF的评论有一点意义.在DBMS之上重新实现DBMS确实不是一个好主意.像这样的元会给你

  • 一个拙劣的系统
  • 维护噩梦

如果你确实需要这种灵活性(对吗?),那么实现允许您在某些表中存储元数据并为数据库中的实际表生成模式的层的时间会更好.

我知道这种系统有几个例子:

我相信还有其他人.

这种设计的最重要的一点是,您的数据库最终实际上是有意义的,并且它使用RDBMS来实现其强度.此外,由于一旦创建了表,这种配置不应该一直发生,它允许用户在需要时微调数据库(主要是索引).

我真的非常强烈地感觉到你提出的那种系统的唯一正确答案是没有.


Fra*_*ans 6

这是一个有趣的想法,但是以这种方式使用SQL可能会随着时间的推移而变得非常痛苦.
如果我能正确理解,您希望用户能够定义数据结构,然后将数据保存到这些结构中.您还希望能够查询它.我想可能还有其他几种方法可以解决这个问题;

  • 那么使用XML呢?允许每个用户按"表"存储XML文件,并只维护它的模式.每个"行"都是具有子元素的XML元素.您可以选择将XML粘贴到SQL中,或者通过其他方式存储它.对于大型数据集,这不会很好,但对于成千上万的记录,它的速度非常快; 我在C#中使用20 + MB XML文件进行了一些测试,并且能够创建它们,读取它们并在不到1秒的时间内解析它们.使用LINQ to XML,您甚至可以构建相当复杂的查询和连接.我不会将XML用于大型企业系统,但是你会惊讶于它将在具有大量内存和快速处理器的现代机器上走多远 - 并且它具有无限灵活性.
  • 您可以使用面向对象的数据库(Matisse等)吗?我自己没有这方面的经验,但我认为你可以很容易地做一些像XML方法但有更好的性能.
  • Amazon Simple DB:如果我没记错的话,这本质上是一个基于名称/值对的数据库,您可以使用它.你的应用程序可以在后台使用它,以避免你必须处理所有的管道?如果你不得不为SQL Server付费,那么亚马逊数据库可能会更便宜,并且可以扩展规模,但没有像关系查询这样的东西.