用于存储表达式及其在文本中出现的数据库模型

时间:2010-06-06 00:01:22

标签: mysql postgresql database-design

我正在做一个统计研究应用程序。我需要根据2个首字母存储单词,这是676个组合,每个单词在文本中的出现次数(最小,最大,平均)。我不确定模型/架构应该是什么样子。将会有很多检查关键字是否已经保留。我感谢你的建议。


编辑:我将使用mysql或postgresql + spring templates

1 个答案:

答案 0 :(得分:1)

除非你有数百万的单词,否则只存储他们的前缀似乎是一个糟糕的计划。

要将新数据添加到表中,您只需编写一个充满传入单词的临时表,然后在导入运行结束时一次性汇总和合并这些数据。就是这样:

BEGIN;
CREATE TEMP TABLE word_stage(word text) ON COMMIT DROP;
COPY word_stage FROM stdin;
-- use pgputcopydata to send all the words to the db...
SET work_mem = 256MB; -- use lots of memory for this aggregate..
CREATE TEMP TABLE word_count_stage AS
    SELECT word, count(*) as occurrences
    FROM word_stage
    GROUP BY word;
-- word should be unique, check that and maybe use this index for merging
ALTER TABLE word_count_stage ADD PRIMARY KEY(word);
-- this UPDATE/INSERT pair is not comodification-safe
LOCK TABLE word_count IN SHARE ROW EXCLUSIVE MODE;
-- now update the existing words in the main table
UPDATE word_count
SET word_count.occurrences = word_count.occurrences + word_count_stage.occurrences,
    word_count.min_occurrences = least(word_count.occurrences, word_count_stage.occurrences),
    word_count.max_occurrences = greatest(word_count.occurrences, word_count_stage.occurrences)
FROM word_count_stage
WHERE word_count_stage.word = word_count.word;
-- and add the new words, if any
INSERT INTO word_count(word, occurrences, min_occurrences, max_occurrences)
  SELECT word, occurrences, occurrences, occurrences
  FROM word_count_stage
  WHERE NOT EXISTS (SELECT 1 FROM word_count WHERE word_count.word = word_count_stage.word);
END;

因此,这会聚合一批有价值的单词,然后将它们应用于单词计数表。在word_stage(word)word_count(word)上建立索引会打开一些可能性,例如,如果两个表都很大,则使用合并,通过尝试一次更新主表中的每一行,您无法轻松完成。更不用说减少word_count中可能产生的垃圾量了。 (虽然在word_count上指定一个像60左右这样的低填充因子是一个好主意,因为你知道它仍然会因为更新而受到一些打击。)

如果您的输入实际上是单词/出现对而不是单词(您的文字不是很清楚),那么您可以取出初始的word_stage表并只复制到word_count_stage,或者可能您需要一个初始表,并希望将该初始表中的DISTINCT值复制到word_count_stage

说真的,我尝试至少在最初使用整个单词作为关键 - 你引用的数字完全在可用性的范围内。另请注意,上面概述的加载方法可以很容易地修改为将单词截断为前两个字符(或以任意方式将其转换为内存键)非常容易,可以通过转换为数据移动到word_count_stage或者甚至在最后通过将转换放入update / insert语句(尽管你可能会失去在临时表上使用索引的好处)。