Py学习  »  DATABASE

需要有关mysql查询[duplicate]的帮助

Rezaul • 4 年前 • 1149 次点击  

想象一个带有一组复选框的web表单(可以选择其中的任何一个或所有)。我选择将它们保存在数据库表的一列中以逗号分隔的值列表中。

现在,我知道正确的解决方案是创建第二个表并正确规范化数据库。实现这个简单的解决方案更快,我想快速地证明这个应用程序的概念,而不必花费太多时间。

我认为在我的情况下,节省的时间和更简单的代码是值得的,这是一个合理的设计选择,还是应该从一开始就规范化它?

还有一些上下文,这是一个小型的内部应用程序,基本上取代了存储在共享文件夹中的excel文件。我这样问也是因为我在考虑清理程序,使其更易于维护。有些事情我并不完全满意,其中之一就是这个问题的主题。

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/47135
 
1149 次点击  
文章 [ 10 ]  |  最新文章 4 年前
Solomon Ucko
Reply   •   1 楼
Solomon Ucko    5 年前

如果有固定数量的布尔字段,可以使用 INT(1) NOT NULL (或 BIT NOT NULL 如果存在) CHAR (0) (可为空)对于每个。你也可以用 SET (我忘记了确切的语法)。

Jerry Coffin
Reply   •   2 楼
Jerry Coffin    13 年前

我可能会采取中间立场:让csv中的每个字段在数据库中变成一个单独的列,但不太担心规范化(至少现在是这样)。在某种程度上,标准化 可以 变得有趣,但是随着所有的数据被塞进一个列中,使用数据库几乎没有任何好处。在对数据进行有意义的操作之前,您需要将数据分成逻辑字段/列/您想调用它们的任何内容。

robin
Reply   •   3 楼
robin    13 年前

是的,它 真糟糕。我的观点是,如果你不喜欢使用关系数据库,那么就寻找一个更适合你的替代方案,有很多有趣的“nosql”项目有一些非常高级的特性。

Community James A Mohler
Reply   •   4 楼
Community James A Mohler    6 年前

我需要一个多值列,它可以实现为一个xml字段

它可以根据需要转换为逗号分隔

querying an XML list in sql server using Xquery 是的。

作为一个xml字段,可以解决一些问题。

使用csv: 无法确保每个值都是正确的数据类型:无法阻止1、2、3、香蕉、5

使用XML: 标记中的值可以强制为正确的类型


使用csv: 无法使用外键约束将值链接到查找表;无法强制引用完整性。

使用XML: 还是个问题


使用csv: 无法强制唯一性:无法阻止1、2、3、3、3、5

使用XML: 还是个问题


使用csv: 如果不获取整个列表,则无法从列表中删除值。

使用XML: 可以删除单个项目


使用csv: 很难搜索列表中具有给定值的所有实体;必须使用效率低下的表扫描。

使用XML: 可以索引XML字段


使用csv: 很难计算列表中的元素数,或执行其他聚合查询。**

使用XML: 不是特别难


使用csv: 很难将值联接到它们引用的查找表中。**

使用XML: 不是特别难


使用csv: 很难按顺序提取列表。

使用XML: 不是特别难


使用csv: 将整数存储为字符串所占用的空间大约是存储二进制整数的两倍。

使用XML: 存储甚至比csv还要糟糕


使用csv: 加上许多逗号字符。

使用XML: 使用标记而不是逗号


简言之,使用xml可以解决分隔列表的一些问题,并且可以根据需要转换为分隔列表

Raj
Reply   •   5 楼
Raj    13 年前

好吧,我在sql server的ntext列中使用键/值对制表符分隔列表已经有4年多了,现在它已经工作了。您确实失去了查询的灵活性,但另一方面,如果您有一个库,它对键值对保持/不保留,那么这不是一个坏主意。

duffymo
Reply   •   6 楼
duffymo    13 年前

是的,我想说真的很糟糕。这是一个合理的选择,但这并不能使它正确或好。

它打破了第一个正常形态。

第二个批评是,将原始输入结果直接放入数据库,而根本不进行任何验证或绑定,会让您面临SQL注入攻击。

你所说的懒惰和缺乏sql知识是新手们的天性。我建议你花点时间把它做好,并把它当作一个学习的机会。

或者让它保持原样,从sql注入攻击中吸取痛苦的教训。

bobbymcr
Reply   •   7 楼
bobbymcr    13 年前

一般来说,只要满足项目的要求,任何事情都是可以辩护的。这并不意味着人们会同意或想为你的决定辩护…

一般来说,以这种方式存储数据是次优的(例如,更难进行有效的查询),如果修改表单中的项,可能会导致维护问题。也许你可以找到一个中间点,用一个整数来表示一组位标志?

OMG Ponies
Reply   •   8 楼
OMG Ponies    13 年前

有很多问题要问:

  • 如何从逗号分隔列表中获取特定值的计数
  • 如何从逗号分隔的列表中获取只有相同2/3/etc特定值的记录

逗号分隔列表的另一个问题是确保值的一致性-存储文本意味着可能会出现拼写错误…

这些都是非规范化数据的症状,并强调了为什么应该始终为规范化数据建模。非规范化 可以 是一个查询优化, 当需求实际出现时应用 是的。

cHao Hammerite
Reply   •   9 楼
cHao Hammerite    12 年前

“一个原因是懒惰”。

这敲响了警钟。你应该这样做的唯一原因是你知道如何“正确地”做,但你已经得出结论,有一个切实的理由不这样做。

已经说过:如果您选择以这种方式存储的数据是您永远不需要查询的数据,那么可能存在以您选择的方式存储它的情况。

(有些用户会对我上一段的说法提出异议,说“你永远不知道将来会增加什么要求”。这些用户要么被误导,要么表明宗教信仰。有时候,按照你之前的要求工作是有好处的。)

Bill Karwin
Reply   •   10 楼
Bill Karwin    4 年前

除了违反 First Normal Form 由于在单个列中存储了重复的值组,逗号分隔的列表还有许多其他更实际的问题:

  • 无法确保每个值都是正确的数据类型:无法防止 1,2,3,香蕉,5
  • 不能使用外键约束将值链接到查找表;无法强制引用完整性。
  • 无法强制唯一性:无法防止 1,2,3,3,3,5号
  • 无法在不获取整个列表的情况下从列表中删除值。
  • 不能存储比字符串列中的内容长的列表。
  • 很难搜索列表中具有给定值的所有实体;必须使用效率低下的表扫描。可能必须使用正则表达式,例如在mysql中:
    idlist REGEXP '[[:<:]]2[[:>:]]' *
  • 很难计算列表中的元素数,或者执行其他聚合查询。
  • 很难将值连接到它们引用的查找表。
  • 很难按顺序提取列表。

为了解决这些问题,您必须编写大量的应用程序代码,重新设计rdbms 已经提供了更有效的 是的。

逗号分隔的列表是错误的,我把它作为我书中的第一章: SQL Antipatterns: Avoiding the Pitfalls of Database Programming 是的。

有时需要使用非规范化,但是 @OMG Ponies mentions ,这些是例外情况。任何非关系优化都会以牺牲数据的其他用途为代价而使一种查询受益,因此请确保您知道哪些查询需要特别处理,以使它们值得非规范化。


* mysql 8.0不再支持这种单词边界表达式语法。