将 Perl 哈希数据存储在数据库中
store Perl hash data in a database
我编写了解析文本文件的 Perl 代码,并使用哈希计算每个 file/record 中美国州缩写出现的次数。我最终得到了这样的结果。
File: 521
OH => 4
PA => 1
IN => 2
TX => 3
IL => 7
我正在努力寻找一种方法将此类哈希结果存储在 SQL 数据库中。我正在使用 mariadb
。因为数据本身的结构是不同的,一个文件会有一些状态,而下一个文件可能有其他状态。例如,一个文件可能只包含几个状态,下一个文件可能包含一组完全不同的状态。我什至无法概念化 table 结构。在数据库中存储此类数据的最佳方式是什么?
有点不清楚你的问题的方向。但是如果你想要一个好的关系模型来存储数据,那就是三个 tables。一个用于文件。一个给各州。一个用于文件中状态的计数。例如:
tables:
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 填充 table 并使用它们。不应再次为每个文件插入它们。
如果您想区分“我知道它是 0. “和“我不知道计数。”,然后将通过缺少相应行进行编码。如果您不想区分它并且没有行意味着 0
的计数,您可以在查询中使用外连接和 coalesce()
来“转换”为 0
。
存储数据的方法有很多种。
为简单起见,请查看以下方法是否适合您的情况table。该解决方案基于使用一个 table 和两个基于 id
和 state
列的索引。
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);
样本SQLSELECT输出
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)
我编写了解析文本文件的 Perl 代码,并使用哈希计算每个 file/record 中美国州缩写出现的次数。我最终得到了这样的结果。
File: 521
OH => 4
PA => 1
IN => 2
TX => 3
IL => 7
我正在努力寻找一种方法将此类哈希结果存储在 SQL 数据库中。我正在使用 mariadb
。因为数据本身的结构是不同的,一个文件会有一些状态,而下一个文件可能有其他状态。例如,一个文件可能只包含几个状态,下一个文件可能包含一组完全不同的状态。我什至无法概念化 table 结构。在数据库中存储此类数据的最佳方式是什么?
有点不清楚你的问题的方向。但是如果你想要一个好的关系模型来存储数据,那就是三个 tables。一个用于文件。一个给各州。一个用于文件中状态的计数。例如:
tables:
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 填充 table 并使用它们。不应再次为每个文件插入它们。
如果您想区分“我知道它是 0. “和“我不知道计数。”,然后将通过缺少相应行进行编码。如果您不想区分它并且没有行意味着 0
的计数,您可以在查询中使用外连接和 coalesce()
来“转换”为 0
。
存储数据的方法有很多种。
为简单起见,请查看以下方法是否适合您的情况table。该解决方案基于使用一个 table 和两个基于 id
和 state
列的索引。
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);
样本SQLSELECT输出
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)