【问题标题】:SQL: how would you save users' own data?SQL:你会如何保存用户自己的数据?
【发布时间】:2011-12-19 12:09:52
【问题描述】:

我正在进行一个涉及时间序列分析的项目,我需要能够让用户上传包含他们自己的时间序列(即带日期的数字)的文件,例如 .csv 文件。然后可以随时访问他们文件中包含的数据,以便在我们的系统中使用。

我怎么能这样做? 我想过的想法:

  1. 每次用户上传文件时创建一个表(并将该表的名称保存在某处)。如果我有很多用户上传大量数据,我最终可能会得到大量表格。
  2. 创建一个大胖怪物表,基本上三四列:值的日期;价值;数据集名称(和/或数据集的所有者)。所有内容都上传到该表中,当 Bob 需要它的天气数据时,我只需选择 (date,value),其中 owner = Bob 和 datasetname = weatherdata。
  3. 在两种解决方案之间:每个用户一张表,并且 Bob 的所有数据集都在 Bob 的表中。
  4. 完全不同:只需将 .csv 文件保存在某处,并在需要时阅读。

我一直在阅读,拥有不同数量的表格是一种不好的做法(我相信这一点)。但是,我的情况与我在此站点上看到的其他问题略有不同(大多数人似乎希望为每个用户创建一个表,而他们应该为每个用户创建一行)。

一些附加信息:

  • 时间序列数据可能包含数十万甚至数百万的观测值
  • 先验,保存后的数据不应被修改。不过,我想让用户将新数据附加到他们的时间序列中会很有用。
  • 先验,我不需要执行复杂的 SQL 选择语句。我只想阅读 Bob 的天气数据,我可能会按时间顺序使用它 - 尽管你永远不知道明天会发生什么。
  • 使用 PostgreSQL 9.1,如果这很重要的话。

编辑 阅读了一些答案,我意识到我可能没有很好地完成我的工作,我应该说我显然已经在 SQL 环境中发展了;我已经有一个用户表;当我写“表”时,我真正的意思是“关系”;我所有的 4 个想法都在某处涉及外键;除非有更好的方法,否则 RDBMS 规范化是范例。 (这一切并不意味着我反对非 sql 解决方案)。

【问题讨论】:

  • PostgreSQL 可能很重要的一个原因是 Postgres 的分区方法 (postgresql.org/docs/9.1/static/ddl-partitioning.html) 本质上包括显式创建多个表并将它们合并到一个视图中——这可能是明显不如其他一些 SQL 的方法有用。但是,我没有在 PostgreSQL 中进行分区的直接经验。
  • 我不会说 4 个相关的表会自动引导一个关系数据库解决方案。相信我,我通常是last people to board the nosql train 中的一员,并且在此之前曾断言relational databases can scale well into the terabytes。但那些是在谈论复杂的业务系统;如果您有一个非常有限的系统,不需要隔离(或内在隔离),那么您不需要 RDBMS。

标签: sql database database-design


【解决方案1】:

我将不得不使用“大胖怪物桌”。这就是关系数据库的工作方式,尽管您应该对其进行规范化(为用户创建一个表,为数据集创建另一个表,为数据点创建另一个表)。拥有多个具有相同模式的表从各个角度来看都是一个坏主意——设计、管理、安全,甚至查询;你确定你永远不想合并来自两个数据集的信息吗?

如果您确实确定每个数据集都是完全隔离的,那么您也可以考虑完全不使用 SQL。 HDF(分层数据格式)字面上是为这个确切的目的而构建的,高效存储和检索“科学数据集”,这些数据集通常是时间序列数据。 HDF 中的“表”字面意思是数据集,它们可以共享定义,可以是多维的(例如一天一维,时间一维),而且它们比 SQL 表便宜得多。

我通常不会试图引导人们远离 SQL,但不寻常的情况有时需要不寻常的解决方案。如果您最终要在 SQL 表(或更多)中获得 十亿 行,并且实际上 没有 其他数据要存储,那么 SQL 可能不是适合您的解决方案。

【讨论】:

  • 或者你可以使用一个组合,一个用于更普通数据的关系数据库和用于时间序列数据的 HDF。
  • 是的,混合将是另一种选择,但需要注意的是它可能有点棘手,因为 HDF 没有事务语义,所以你必须非常小心跨数据库的一致性。但这与任何 SQL/noSQL 混合并没有太大区别。
  • @Aaronaught 感谢您的回答。但是,我不确定我是否理解您的最后一句话:“如果您实际上没有其他数据要存储”。我有一个完整的系统,用户和其他(重要的)东西保存在 PostgreSQL 表中,所以我想我不是那种情况?至于数据集“特征”,我只需要保存数据 - 并且能够将数据集链接到它们的所有者。
  • 无论如何,由于我已经在 SQL 中有很多东西,如果我决定选择 noSQL 路线,它将在某处混合。
  • @Arthur:好的,这在您的问题/cmets 中并不明显——听起来您好像刚刚开始这个设计。混合系统可以工作,尽管您必须注意操作顺序 - 为错误或瞬态问题做好准备,以在跨系统写入过程中中断进程并导致系统之间的状态不一致,并确保您有一个跟踪和修复这些的方法。
【解决方案2】:

你的想法都是完成任务的好方法(希望我没看错)。

关系数据库呢?例如具有用户名、上传时间和唯一 dataid 的表,然后将 dataid 链接到另一个包含 dataid 外键和原始文件数据的表。这将使用户表保持在最低限度(并且您可以将其与另一个表合并,例如包含用户详细信息)。为用户设置一个单独的表,然后为密码设置另一个表,为电子邮件设置另一个表,然后再为数据设置 5 个表可能是不好的做法,但我个人认为将文件与用户数据分开并没有什么问题。

您使用什么语言来处理数据?这也可能是一个决定因素。

希望这会有所帮助:)

汤姆

【讨论】:

    【解决方案3】:

    好的,我认为选项 2 是最好的,创建额外的表只是维护的一场噩梦,并且会让您面临很多错误等。选项 4 有点吸引人,但我仍然认为数据库应该能够应对这种任务。

    我想我会像这样构建我的表格:

    用户表 - 用户 ID、名称等

    Row - 上传数据中的每一行(rowid 等)

    RowInDataSet - 行 ID、DataSetID

    DataSet - DataSetID、上传日期、UploadBy 等

    这可以让您稍微分解数据并使其易于维护。如果您正确索引这些表,那么存储大量数据应该不是问题。

    【讨论】:

    • 感谢您的回答!但我不确定我是否理解......值和它们的日期存储在“行”中,对吗? “RowInDataSet”到底有什么意义?我不能在 Row 表中有一个 DataSetID 外键列吗?还是将其放在单独的表格中更有效?
    • @Arthur 我认为这是您必须测试才能获得准确答案的东西,我不是 DBA,但我发现在某些情况下我这样做提高了性能,并且这是我看到的其他数据库表设计方式相同的方式
    【解决方案4】:

    可能设计的 T-SQL* 示例:

    CREATE TABLE dbo.Datasets (
        ID          int NOT NULL IDENTITY(1,1),
        OwnerUserID int NOT NULL,
        Loaded      datetime NOT NULL,
    
       CONSTRAINT FK_Datasets_Users
           FOREIGN KEY ( OwnerUserID )
           REFERENCES dbo.Users ( ID )
    );
    
    CREATE TABLE dbo.DatasetValues (
        DatasetID   int NOT NULL,
        Date        datetime NOT NULL,
        Value       int NOT NULL,
    
        CONSTRAINT FK_DatasetValues_Datasets
            FOREIGN KEY ( DatasetID )
            REFERENCES dbo.Datasets ( ID )
    );
    

    该设计模拟了您的问题中隐含的两个“实体”——正在加载的时间序列数据和时间序列数据的

    *对于 SQL Server;我知道你说的是 PostgreSQL 9.1,但我很确定你可以很容易地翻译。

    【讨论】:

    • +1 用于包含 DDL SQL,尽管我认为单个用户可能有多个数据集 - 正如 Aaronaught 所建议的那样,为用户和数据集提供单独的表可能会更好。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-14
    • 2011-03-21
    相关资源
    最近更新 更多