JnB*_*ymn 99 sql linq linq-to-entities database-design linq-to-sql
所以,每迈赫达德的回答一个相关的问题,我得到它是一个"正确"的数据库表列中不存储列表.相反,您应该创建另一个表,该表有效地保存所述列表的元素,然后直接或通过联结表链接到它.但是,我想要创建的列表类型将由唯一项组成(与链接问题的结果不同)例).此外,列表中的项目是显式排序的 - 这意味着如果我将元素存储在另一个表中,我每次访问它时都必须对它们进行排序.最后,该列表基本上是原子的,因为任何时候我希望访问列表,我将要访问整个列表而不仅仅是它的一部分 - 因此,必须发出数据库查询以聚集在一起的部分似乎很愚蠢列表.
AKX的解决方案(上面链接)是序列化列表并将其存储在二进制列中.但这似乎也不方便,因为这意味着我不得不担心序列化和反序列化.
有没有更好的解决方案?如果是没有更好的解决办法,那么为什么呢?看来这个问题应该不时出现.
...更多信息让你知道我来自哪里.一旦我刚刚开始理解SQL和数据库,我就开始使用LINQ to SQL了,所以现在我有点被宠坏了因为我希望能够处理我的编程对象模型而不必考虑对象如何被查询或存储在数据库中.
谢谢大家!
约翰
更新:所以在我得到的第一批答案中,我看到"你可以使用CSV/XML路线......但不要!".所以现在我正在寻找原因的解释.请给我一些很好的参考.
另外,为了让您更好地了解我的目标:在我的数据库中,我有一个Function表,它将包含(x,y)对的列表.(该表还有其他信息对我们的讨论没有影响.)我永远不需要看到(x,y)对列表的一部分.相反,我将采取所有这些并在屏幕上绘制它们.我将允许用户拖动节点以偶尔更改值或向绘图添加更多值.
Ada*_*son 162
不,没有"更好"的方法将一系列项目存储在一个列中.关系数据库被设计专门用于存储每行/列的组合的一个值.为了存储多个值,您必须将列表序列化为单个存储值,然后在检索时对其进行反序列化.没有其他方法可以做你正在谈论的事情(因为你所谈论的是一个坏主意,一般来说,永远不应该这样做).
我知道你认为创建另一个表来存储该列表是愚蠢的,但这正是关系数据库的作用.你正在进行一场艰苦的战斗并且没有任何理由违反关系数据库设计的最基本原则之一.既然你声明你刚学习SQL,我强烈建议你避免这个想法,并坚持使用经验丰富的SQL开发人员推荐给你的实践.
您违反的原则称为第一范式,这是数据库规范化的第一步.
在事情简单化的风险,数据库标准化定义是基于数据你的数据库的过程是,这样您就可以编写针对它明智的,一致的查询,并能够轻松地维护它.规范化旨在限制数据中的逻辑不一致和损坏,并且有很多级别.关于数据库规范化的维基百科文章实际上非常好.
基本上,规范化的第一个规则(或形式)表明您的表必须表示关系.这意味着:
最后一点显然是这里的重点.SQL旨在为您存储您的集合,而不是为您提供一个"桶"供您自己存储集.是的,这是可能的.不,世界不会结束.但是,您已经通过立即使用ORM来了解SQL以及与之相关的最佳实践.LINQ to SQL非常棒,就像图形计算器一样.本着同样的精神,但是,他们应该不被用作替代知道如何处理他们雇用实际工作.
您的列表现在可能完全是"原子的",并且对于此项目可能不会更改.但是,你会养成在其他项目中做类似事情的习惯,并且你最终(可能很快)遇到一个场景,你现在正在拟合你的快捷n列表中的列表接近完全不合适的方法.在为您要存储的内容创建正确的表时,没有太多额外的工作,并且当他们看到您的数据库设计时,您不会被其他SQL开发人员嘲笑.此外,LINQ to SQL将会看到您的关系,并自动为您的列表提供适当的面向对象的接口.为什么你会放弃ORM为你提供的便利,以便你可以执行非标准和不明智的数据库hackery?
小智 9
我见过许多人这样做(这可能不是最好的方法,如果我错了,请纠正我):
我在下面给出了我在示例中使用的表格(该表格包含您给予特定女友的昵称.每个女朋友都有一个唯一的ID):
nicknames(id,seq_no,names)
Run Code Online (Sandbox Code Playgroud)
假设您希望在id下存储许多昵称.这就是我们包含一个seq_no
字段的原因.
现在,将这些值填充到表中:
(1,1,'sweetheart'), (1,2,'pumpkin'), (2,1,'cutie'), (2,2,'cherry pie')
Run Code Online (Sandbox Code Playgroud)
如果你想找到你给你的女朋友id 1的所有名字,你可以使用:
select names from nicknames where id = 1;
Run Code Online (Sandbox Code Playgroud)
简单回答:当且仅当您确定该列表将始终用作列表时,然后在您的末尾使用一个不会在列表中使用的字符(例如“\0”)将列表连接在一起文本永远,并存储。然后当你检索它时,你可以用'\0'分割。当然还有其他方法可以解决这些问题,但这些方法取决于您的特定数据库供应商。
例如,您可以将 JSON 存储在 Postgres 数据库中。如果您的列表是文本,而您只是希望列表不再麻烦,那么这是一个合理的妥协。
其他人大胆地提出了序列化的建议,但我并不认为序列化是一个好主意:关于数据库的部分巧妙之处在于,用不同语言编写的多个程序可以相互通信。如果 Lisp 程序想要加载它,那么使用 Java 格式序列化的程序不会做得那么好。
如果你想要一个好的方法来做这种事情,通常有可用的数组或类似类型。例如,Postgres 提供数组作为类型,并允许您存储文本数组,如果这是您想要的,并且使用 JSON 的MySql和MS SQL也有类似的技巧,IBM 的 DB2 也提供了一个数组类型(在他们的自己有用的文档)。如果不需要这个,这将不会如此普遍。
走那条路你失去的是列表的概念,即一系列按顺序排列的东西。至少在名义上,数据库将字段视为单个值。但如果这就是你想要的,那么你应该去争取。这是你必须为自己做出的价值判断。
除了其他人所说的之外,我建议您比现在更长远地分析您的方法。目前的情况是,物品是独一无二的。目前的情况是,重新排序这些项目需要一个新的列表。目前几乎要求该列表很短。尽管我不了解领域的具体情况,但认为这些要求可能会改变并不奇怪。如果你序列化你的列表,你就会陷入一种僵化的境地,而这在更规范化的设计中是不必要的。顺便说一句,这并不一定意味着完整的多:多关系。您可以只有一个子表,其中包含父表的外键和项目的字符列。
如果您仍然想继续序列化列表,您可以考虑将列表存储在 XML 中。某些数据库(例如 SQL Server)甚至具有 XML 数据类型。我建议使用 XML 的唯一原因是,几乎按照定义,这个列表需要很短。如果列表很长,那么序列化它通常是一种糟糕的方法。如果您采用 CSV 路线,则需要考虑包含分隔符的值,这意味着您必须使用带引号的标识符。假设列表很短,那么无论您使用 CSV 还是 XML,可能都没有太大区别。