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

问题描述 投票:0回答:2

以此表为例:

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

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

谢谢!!

mysql sql database
2个回答
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
投票

为了扩大已经说过的内容:

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

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

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

也许使用另一种数据库类型更好?

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

© www.soinside.com 2019 - 2024. All rights reserved.