【问题标题】:How to add multiple columns in a table with HSQLDB?如何使用 HSQLDB 在表中添加多个列?
【发布时间】:2015-09-26 09:46:58
【问题描述】:

我一直在尝试使用带有 HSQLDB 的 ALTER TABLE 命令向表中添加 2 列,但没有成功。我知道 MySQL 和其他系统支持它,但为什么 HSQLDB 不支持它?也许我使用了错误的语法,我不知道。我也知道我可以一一添加,但我的应用程序需要添加 1000 列,而且一一添加太慢了。

我使用 HSQLDB 的原因是我需要在文件模式下使用它。我也试过SmallSQL,但是比HSQLDB慢很多。

【问题讨论】:

  • 具有 1000 列的表通常表示数据库设计不佳。你能解释一下为什么你认为你需要这么多列吗?为什么不能用最初的 create table 语句创建它们?
  • 关于问题:“但为什么 HSQLDB 不支持它”。答案出人意料地简单:因为还没有人实施它。这是一个开源项目,所以如果你真的需要,你可以添加这个功能。
  • 是的,我听说过大型系统。我维护了几个具有 1TB 和更多数据的数据库。它们都没有超过 200 列的表。您所描述的内容听起来好像您实际上想要一个适当规范化的一对多关系。如果您的客户观察到数千个“事物”,您应该在数据库中插入一千行 。而且我怀疑 HSQLDB 首先是“大数据”的正确选择。
  • 听起来你仍然不需要数千列。顺便说一句,您可能会考虑使用 Postgres 而不是 HSQLDB。它支持非常高效的键值存储 (hstore) 和 JSON,我相信 Postgres 将比 HSQLDB 更适合处理“大数据”。但我认为既不需要键/值也不需要 JSON 解决方案——这也可以使用适当的规范化模型来处理。
  • 您只需要三个表格:问卷、问答(可能是一个包含用户信息的表格)。类似:sqlfiddle.com/#!15/0a4e5/1 不知道你所说的“split the data”是什么意思

标签: hsqldb


【解决方案1】:

您不需要数千列。这是三个表之间的标准一对多关系:questionairequestionanswer

create table questionaire 
(
  id              integer not null primary key,
  customer_name   varchar(100) not null
);

create table question 
(
  id                integer not null primary key,
  questionaire_id   integer not null references questionaire,
  question_text     varchar(20000),
  sort_order        integer
);

create table answer 
(
  question_id   integer not null references question,
  answer_text   varchar(20000),
  user_name     varchar(50) not null,
  primary key (question_id, user_name)
);

实际上,您实际上不会将用户名存储在answer 表中。如果您指定了登录用户,您可能还需要一个user_account 表,而question 表将引用user_account 表。

您可以轻松查询此模型,而无需恢复为键/值存储或 JSON

从客户那里获取所有问卷

select *
from  questionaire qu
where customer_name = 'Some company';

获取所有问卷和每位客户的问题数量

select qu.customer_name, 
       count(distinct qu.id) as num_questionaires,
       count(q.id) as total_questions
from  questionaire qu
  join question q on qu.id = q.questionaire_id 
group by  qu.customer_name;

从特定用户那里获取问卷的所有答案

select q.question_text, a.answer_text
from answer a 
  join question q on q.id = a.question_id 
  join questionaire qu on qu.id = q.questionaire_id 
where qu.id = 1
  and a.user_name = 'Marvin'
order by q.sort_order;

有点复杂,但即使有数千个问题和答案也可能足够快:查找尚未回答所有问题的用户

select aq.user_name, aq.questionaire_id, aq.answered_questions, tq.num_questions
from (
  select a.user_name, q.questionaire_id, count(*) as answered_questions
  from answer a 
    join question q on q.id = a.question_id 
  group by a.user_name, q.questionaire_id
) aq join (
     select questionaire_id, count(*) as num_questions
     from question
     group by questionaire_id
  ) tq on tq.questionaire_id = aq.questionaire_id
where aq.answered_questions < tq.num_questions;

SQLFiddle 示例:http://sqlfiddle.com/#!15/0a4e5/1


您也不应该尝试将每个问题(或答案)的行转换为 SQL 中的列 - 您最终达到数据库可以管理的列数的一些限制。关系数据库旨在处理行,大量行 - 而不是“数千列”。将行转换为列通常在应用程序的表示层中完成(或例如在电子表格中使用 Pivot 函数)

【讨论】:

  • 感谢您的回答。这真的很有帮助。我忘了提到虽然每个“答案”可以是任何类型,而不仅仅是文本。它可以是数字、日期、GPS 坐标、二进制文件或多项选择。这就是我们对不同问题使用不同列的原因。我只是忘记了。这就是我们有数千列的原因。转向无 SQL 将解决可伸缩性问题。我们正在评估 HBase。
  • @melios:您可以在answer 表中通过不同的列(具有不同的类型)存储多种类型的答案。但是我很难理解你为什么首先要为此评估 HSQLDB。如果您对“大数据”很认真,那么 HSQLDB 可能不是一个好的选择。 Postgres 或任何其他基于服务器的 DBMS 将是一个非常更好的选择。其次,您已经明确下定决心,关系解决方案行不通(尽管您似乎缺乏该领域的经验),那么为什么要浪费时间寻找关系模型呢?
  • 我们的平台已经运行在一个集群的 MySQL 服务器上,该服务器托管了数百个应用程序,数据总大小超过 10T。该平台是一组 8-9 个组件。我最初的 HSQLDB 问题只是整个业务中的一个很小的子项目。其中一个组件需要本地文件数据库,而不是数据库服务器,我们正在评估此类数据库,例如 SmallSql、SQLite、HSQLDB 和 H2 数据库。我不想向任何事情证明我的经验,我在软件开发领域已有 18 年以上的经验,而且决策取决于更多的事情,而不仅仅是我的经验。
  • 只是为了让你知道,我已经通过使用 H2 数据库解决了原始问题。大数据问题是关于核心数据库服务器(MySQL)的,与 HSQLDB 完全无关。这是我继承的一个平台,它是在 10 年前创建的,具有数千列的不灵活模型。我在 Hadoop/HBase/Cassandra/MongoDB 方面的丰富经验使决策者考虑迁移到在大数据集群模式下性能更好的无 SQL 数据库。我不再需要 RDBMS 方面的经验,因为这一切都将成为过去。
猜你喜欢
  • 2019-09-22
  • 2016-04-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-12
  • 2017-09-09
  • 2012-01-01
  • 2012-09-16
相关资源
最近更新 更多