【问题标题】:store Perl hash data in a database在数据库中存储 Perl 哈希数据
【发布时间】:2022-01-16 15:33:29
【问题描述】:

我编写了解析文本文件的 Perl 代码,并使用哈希来计算美国州缩写出现在每个文件/记录中的次数。我最终得到了这样的结果。

File: 521
OH => 4
PA => 1
IN => 2
TX => 3
IL => 7

我正在努力寻找一种将此类哈希结果存储在 SQL 数据库中的方法。我正在使用mariadb。由于数据本身的结构不同,一个文件会有一些状态,而下一个文件可能有其他状态。例如,一个文件可能只包含几个状态,下一个文件可能包含一组完全不同的状态。我什至无法概念化表结构。在数据库中存储此类数据的最佳方式是什么?

【问题讨论】:

  • DBIx::Class 或其他 ORM(如果您正在寻找程序员效率)?
  • metacpan.org/pod/Storable。包装器可用。
  • 也许使用JSON data type ?
  • 什么是File: 521521 是文件名还是某种 ID?你会对这些数据做什么样的操作?有许多免费的数据库。有时,对于简单的任务,它并不需要完全实现的数据库。如果您想存储/读取哈希数据,那么JSONYAML 可能就足够了。如果操作非常基础,那么SQLite 可能是一个不错的选择。
  • 请通过编辑而非 cmets 进行澄清。 PS这个不清楚。 “数据本身的结构变化”究竟是什么意思?在介绍什么 DB 设计方法之后,您第一次遇到什么困难?现在,您实际上是在要求我们(重新)编写带有定制教程的教科书。 PSHow do you effectively model inheritance in a database?

标签: sql database perl database-design mariadb


【解决方案1】:

有许多可能的方式来存储数据。

为简单起见,请查看以下方法是否适合您的案例。该解决方案基于使用一个表,该表具有两个基于idstate 列的索引。

CREATE TABLE IF NOT EXISTS `state_count` (
    `id`        INT NOT NULL,
    `state`     VARCHAR(2) NOT NULL,
    `count`     INT NOT NULL,
    INDEX `id` (`id`),
    INDEX `state` (`state`)
);

INSERT INTO `state_count`
    (`id`,`state`,`count`)
VALUES
    ('251','OH',4),
    ('251','PA',1),
    ('251','IN',2),
    ('251','TX',3),
    ('251','IL',7);

示例 SQL SELECT 输出

MySQL [dbs0897329] > SELECT * FROM state_count;
+-----+-------+-------+
| id  | state | count |
+-----+-------+-------+
| 251 | OH    |     4 |
| 251 | PA    |     1 |
| 251 | IN    |     2 |
| 251 | TX    |     3 |
| 251 | IL    |     7 |
+-----+-------+-------+
5 rows in set (0.000 sec)
MySQL [dbs0897329]> SELECT * FROM state_count WHERE state='OH';
+-----+-------+-------+
| id  | state | count |
+-----+-------+-------+
| 251 | OH    |     4 |
+-----+-------+-------+
1 row in set (0.000 sec)
MySQL [dbs0897329]> SELECT * FROM state_count WHERE state IN ('OH','TX');
+-----+-------+-------+
| id  | state | count |
+-----+-------+-------+
| 251 | OH    |     4 |
| 251 | TX    |     3 |
+-----+-------+-------+
2 rows in set (0.001 sec)

【讨论】:

    【解决方案2】:

    您的问题的方向有点不清楚。但是如果你想要一个好的关系模型来存储数据,那就是三个表。一个用于文件。一份给各州。一个用于对文件中的状态进行计数。例如:

    表格:

    CREATE TABLE file
                 (id integer
                     AUTO_INCREMENT,
                  path varchar(256)
                       NOT NULL,
                  PRIMARY KEY (id),
                  UNIQUE (path));
    
    CREATE TABLE state
                 (id integer
                     AUTO_INCREMENT,
                  abbreviation varchar(2)
                               NOT NULL,
                  PRIMARY KEY (id),
                  UNIQUE (abbreviation));
    
    CREATE TABLE occurrences
                 (file integer,
                  state integer,
                  count integer
                        NOT NULL,
                  PRIMARY KEY (file,
                               state),
                  FOREIGN KEY (file)
                              REFERENCES file
                                         (id),
                  FOREIGN KEY (state)
                              REFERENCES state
                                         (id),
                  CHECK (count >= 0));
    

    数据:

    INSERT INTO files
                (path)
                VALUES ('521');
    
    INSERT INTO states
                (abbreviation)
                VALUES ('OH'),
                       ('PA'),
                       ('IN'),
                       ('TX'),
                       ('IL');
    
    INSERT INTO occurrences
                (file,
                 state,
                 count)
                VALUES (1,
                        1,
                        4),
                       (1,
                        2,
                        1),
                       (1,
                        3,
                        2),
                       (1,
                        4,
                        3),
                       (1,
                        4,
                        7);
    

    当然会重复使用这些状态。用所有 50 个填满表格并使用它们。不应为每个文件再次插入它们。

    如果您想区分“我知道它是 0”,您可以使用 0 中的 count 显式填充 occurrences,用于未出现相应状态的文件。和“我不知道计数。”,然后将通过缺少相应行进行编码。如果您不想区分这一点并且没有行意味着计数为 0,则可以在查询中使用外连接和 coalesce() 来“翻译”为 0

    【讨论】:

    • 我相信这是一种非常有效的方法。不过,我很想只创建一个包含一个 ID 列和每个州多 48 个列的表——不需要阿拉斯加和夏威夷。我知道它的效率会降低,但表中的记录不应超过 5,000 条。
    • @gatorreina:一旦你想对数据进行查询以进行分析,这种电子表格方式可能会咬你一口。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-30
    • 2011-06-10
    • 1970-01-01
    • 2012-11-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多