我正在开展一个项目,其中我有一组关键字[abc,xyz,klm] `。我还有一堆文本文件,内容为[1.txt,2.txt,3.txt] 。
我正在做的是将关键字与文本文件碰撞,以找到关键字出现的行,并且可以多次执行此操作。所以我想为每次出现存储ID (text file name without .txt), Extracted_Data, Line_Number, Spwaned_Across (keyword may be spread across 2 lines)
。
我决定为每个关键字创建一个表来存储这些数据。
表:abc,xyz,klm
表abc样本数据:
ID Extracted_Data Line_Number Spawned_Across
12 MySQL is wonderful. What is 'abc' 34 1
所以我最终得到了每个关键字的表格。在我的项目中,大约有150个关键字,它可以增长。所以有150个表。
为什么我选择这样做?
现在我需要查找关键字是否存在于文件中,我相信将来我会被要求显示文件中的位置或方式。我打算为每个新关键字自动创建一个表,这样我就不必手动创建每个关键字或者包含100列的巨型表。
我做出了正确的决定吗?非常感谢您的意见。
答案 0 :(得分:6)
不要那样做。没有针对动态表名优化数据库库,并且每次要访问表时,最终都必须从头开始创建查询。另外,您如何回答“我在文件12的第34行找到哪些数据”这样的问题?
你需要三张桌子。在PostgreSQL语法[*]中,那就是:
CREATE TABLE source (sourceid SERIAL, filename VARCHAR NOT NULL);
CREATE TABLE keyword (keywordid SERIAL, keyword VARCHAR NOT NULL);
CREATE TABLE location (locationid SERIAL,
sourceid INTEGER NOT NULL REFERENCES source(sourceid),
keyword INTEGER NOT NULL REFERENCES keyword(keywordid),
data VARCHAR NOT NULL,
line INTEGER NOT NULL,
span INTEGER NOT NULL);
当您开始处理新文本文件时,请创建一个新的source
元组并记住它的sourceid。当您遇到关键字时,请为其插入新记录并记住其关键字ID或查找旧记录。然后将该sourceid,keywordid和其他相关数据插入location
。
回答我之前提出的问题:
SELECT * FROM
location JOIN source ON location.sourceid = source.sourceid
JOIN keyword ON location.keywordid = keyword.keywordid
WHERE
source.filename = 'foo.txt' AND
location.line = 34;
是的,以“正确”的方式预先做更多工作,但是你会在性能,易维护性和易于使用结果方面获得100万倍的回报。
[*] MySQL的语法类似,但我不记得它,你可以很容易地找出差异。
答案 1 :(得分:5)
我不明白为什么你不能将关键字沿着数据存储在一个表中。
ID Keyword Extracted_Data Line_Number Spawned_Across
12 abc Abc or xyz?.. 31337 1
12 xyz Abc or xyz?.. 31337 1
12 xyz just xyz here 66666 1
13 xyz xyz travels! 123 1
因此,您必须按关键字或按文件或两者查询,所有数据都存在。要进一步规范化,您可以将关键字分别存储在“keywords”表中,并仅将外键保留在“occurences”表中。
除了主键之外,命名“ID”并不是很受欢迎。
答案 2 :(得分:2)
这绝对是一个非常糟糕的决定。
数百万行优于数百万个表。
使用合适的外键创建2个表,你会没事的。
我将被要求显示文件中的位置或方式。
这仍然可以在2个表中完成
答案 3 :(得分:1)
我不认为这是有效率的。我甚至不确定关系数据库是否适合这项工作。
新关键字意味着更多表格。那是不可扩展的。
关键字和文件让我想到索引和非结构化搜索。我会在关系数据库之前考虑Lucene。