小编典典

Mysql:将数据数组存储在单个列中

sql

在此先感谢您的帮助。

好吧,这就是我的情况。我有一个Web系统,该系统基于超声波计创建的样本进行一些与噪声相关的计算。最初,数据库仅存储这些计算的结果。但是现在,我被要求也自己存储样本。每个样本只是一个300或600个数字的列表,每个数字都有一个小数。

因此,我想到的最简单的方法是在表中添加一列,该列存储给定样本的所有计算。此列应包含数字列表。

那么我的问题是:将这一数字列表存储在单列中的最佳方法是什么?

要考虑的事情:

  • 如果该列表可以由PHP和javascript读取且没有其他复杂性,那就太好了。
  • 该列表仅在整体检索时才有用,这就是为什么我不愿对其进行规范化的原因。而且,在该列表上进行的计算非常复杂,并且已经用PHP和javascript进行了编码,因此我不会在给定列表的元素上进行任何SQL查询

另外,如果有比存储它更好的方法,我很想知道它们

非常感谢,并祝您有个美好的一天/晚上:)


阅读 263

收藏
2021-05-23

共1个答案

小编典典

首先,您真的不想这样做。RDBMS中的一列是原子的,因为它只包含一个信息。试图在一个列中存储多个数据违反了第一标准格式。

如果绝对必须这样做,则需要将数据转换为可以存储为单个数据项(通常是字符串)的形式。您可以使用PHP的serialize()机制,XML解析(如果数据恰好是文档树),json_encode()等。

但是,您如何有效地查询此类数据?答案是你做不到。

另外,如果以后有人接管您的项目,您真的会惹恼他们,因为数据库中的序列化数据非常难以使用。我知道,因为我继承了此类项目。

我是否提到过您真的不想这样做?您需要重新考虑您的设计,以便可以根据原子行更轻松地存储它。例如,将另一个表用于此数据,并使用外键将其与主记录相关联。由于某种原因,它们被称为关系数据库。

更新 :有人问我有关数据存储的要求,例如单行存储是否便宜。答案是,在典型情况下,不是,在答案是肯定的情况下,您所付出的代价是不值得的。

如果使用2列相关表(该样本所属记录的外键使用1列,单个样本使用1列),则每列在最坏情况下将需要16个字节(longint键列为8个字节,而8个字节为8个字节)用于双精度浮点数)。对于100条记录,即1600字节(忽略db开销)。

对于序列化的字符串,最好在字符串中每个字符存储1个字节。您不知道字符串将要持续多长时间,但是如果我们假设100个样本的所有存储数据都经过某些人为的巧合,都落在10000.00和99999.99之间,则小数点后只能有2位数字,那么您重新查看每个样本8个字节。在这种情况下,您只保存了外键的开销,因此所需的存储量为800字节。

当然,这是基于许多假设的,例如字符编码始终为每个字符1个字节,组成样本的字符串不得超过8个字符,等等。

但是,当然,用于序列化数据的任何机制也会产生开销。绝对最简单的方法CSV表示在每个样本之间添加逗号。这会将n-1个字节添加到存储的字符串中。因此,上面的示例现在将是899个字节,并且采用了最简单的编码方案。JSON,XML甚至PHP序列化都添加了比这更多的开销字符,并且您很快就会拥有比1600字节长得多的字符串。所有这些都是在假设1字节字符编码的情况下进行的。

如果您需要对样本建立索引,则对字符串的数据需求将成比例地增长,因为在存储方面,字符串索引比浮点列索引要昂贵得多。

当然,如果您的样本开始添加更多数字,则数据存储会进一步增加。即使在最佳情况下,也无法将39281.3392810的8个字节存储为字符串。

而且,如果数据已序列化,则数据库将无法操作。您无法对样本进行分类,对样本进行任何数学运算,数据库甚至都不知道它们是数字!

不过,老实说,如今的存储价格非常便宜,您可以花很少的钱购买多个TB驱动器。存储真的那么重要吗?除非您有数亿条记录,否则我怀疑是这样。

您可能想看看一本叫做《 SQL Antipatterns》的书

2021-05-23