有没有办法在SQL中只将属性添加到1行?

时间:2017-12-24 17:29:00

标签: mysql sql database

以此表为例:

CREATE TABLE UserServices (
    ID BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    Service1 TEXT,
    Service2 TEXT,
    .
    .
    . 
) ENGINE = MYISAM;

每个用户都有不同数量的服务,因此我们假设该表以10列开头,为每个用户提供服务。如果一个用户将拥有11个服务,那么所有其他用户是否也必须拥有11个列?现在当然它是一个表和行需要具有相同数量的列,但它似乎是一个可怕的内存浪费。也许使用其他数据库类型更好?

谢谢!

2 个答案:

答案 0 :(得分:1)

存储一大堆空值实际上并不是“浪费内存”,因为空间可以忽略不计 - 硬盘成本为每千兆字节便士,程序员花费数十/数百美元/小时所以燃烧空间肯定是经济的而且它是回避并不是一个很好的论据。

有一个更好的论点,正如其他人所说的那样;数据库不为表中的特定ID执行可变数量的列,但是它们每个ID都会执行可变数量的行。这就是DB的设计方式:列是固定的,行是可变的。数据库在查询,存储,检索,内部设计等方面所做的一切都针对这种模式进行了优化

有一些完善的操作(称为枢轴),可以在查询时将垂直排列的数据转换为水平(带空值),因此您不必水平存储数据

这是一个支点示例:

Table:
ID, ServiceIdentifier, ServiceOwner
1, SV1, John
1, SV2, Sarah
2, SV1, Phil
2, SV2, John
2, SV3, Joe
3, SV2, Mark

SELECT
  ID,
  MAX(CASE WHEN ServiceIdentifier = 'SV1' THEN ServiceOwner END) as SV1_Owner,
  MAX(CASE WHEN ServiceIdentifier = 'SV2' THEN ServiceOwner END) as SV2_Owner,
  MAX(CASE WHEN ServiceIdentifier = 'SV3' THEN ServiceOwner END) as SV3_Owner
FROM
  Table
GROUP BY
  ID


Result:
ID SV1_Owner SV2_Owner SV3_Owner
1  John      Sarah
2  Phil      John      Joe
3            Mark

如上所述,水平存储数据并不是一笔巨大的成本,如果您确定该表永远不会更改/不需要每周添加新列来应对新服务等,那么它可能是一个合理的开发人员优化只是让列充满空值。如果您要定期添加列,或者有一天会有数千个服务,那么垂直存储就必须按照它的方式进行

答案 1 :(得分:1)

稍微讨论一下已经说过的内容:

  

有没有办法在SQL中只向1行添加属性?

不,这对于关系数据库(SQL)的工作原理有什么基础 - 以及任何版本的SQL,无论是mysql,t-sql等等。如果你有一个表 - 并且你想要为该表添加一个属性,它将成为另一个列,并且该列将存在于每一行。不只是关系数据库 - 这就是表的工作方式。

但是,那不是任何人都会这样做的。你会做什么是艾伦建议的 - 一个单独的服务表,然后是第三个表(他建议将其命名为“UserServices'”)将两者联系起来。这不是一次性的建议 - 几乎是"""这样做的方式。没有浪费。

  

也许使用其他数据库类型更好?

可能,如果你想要一些限制较少的东西,那么你可以使用SQL以外的东西。由于SQL占主导地位,因此通常将所有内容归类为NOSQL。 - Mongo是目前最受欢迎的NOSQL数据库,这就是RC提出它的原因。

相关问题