字典的表格设计,可以包含许多不同拼写的单词

时间:2015-11-20 13:16:16

标签: ms-access database-design

我正在使用Microsoft Access中的小型个人词典数据库(2013版)。英语中有很多单词有两个甚至更多的拼写。实事求是地说,没有那么多单词有三个,更不用说四个拼写了。然而,它们确实存在。示例包括 aerie / aery / eyrie / eyry (带有四种拼写的单词)和 ketchup < / em> / catsup / catchup (一个包含三个拼写的单词)。更不用说英语实际上充斥着有两个拼写的单词。每个人都知道(英国和英国拼写系统之间的差异立即浮出水面)。因此,我需要设计我的表格,使设计没有明显的缺陷。我将逐步解释数据库应该是什么样子,并介绍我在当前设计中遇到的问题。所以,我们走了。

显然,所有单词都应存储在同一个表中。而且我不打算包含设计的不相关方面,例如可能属于表格的其他列(实际上,数据库要复杂得多)。让我们关注最重要的部分。这里的 Words 表包含一些预先填充的样本数据,如下所示:

+---------+-----------+
| word_id | word      |
+---------+-----------+
|       1 | ketchup   |
|       2 | catsup    |
|       3 | catchup   |
|       4 | moneyed   |
|       5 | monied    |
|       6 | delicious |
+---------+-----------+

为了跟踪一组相同的单词,但只有不同的拼写,可能明智的做法是选择其中一个作为主要单词而将其他单词作为其子单词。这里的图表向您展示了我如何设想(这里, ketchup 有钱是主要词,其他所有儿童词):

enter image description here

所有这些信息都会放在一个新表中,我们称之为 Alternative Spellings 表(列 word_id alt_spell_word_id 正在进行中成为表的复合主键的一部分:

+---------+-------------------+
| word_id | alt_spell_word_id |
+---------+-------------------+
|       1 |                 2 |
|       1 |                 3 |
|       4 |                 5 |
+---------+-------------------+

以下是“访问关系”面板中的所有内容(请注意,我已在 Words 表的 word_id 列之间强制执行参照完整性和替代拼写表的 word_id 列,并检查级联删除相关记录选项):

enter image description here

虽然直截了当,但这是我迄今为止唯一能够提出的设计。我认为基本上会这样做。这很简单。然而,这种设计的问题有三个:

1:这不是一个严重的问题,但我仍然希望听到你的想法。每当我在 Word详细信息表单中查找单词时,我都必须浏览整个 Alternative Spellings 表以查看是否存在有其他与之相关的拼写或者是否是儿童单词。因此,我必须同时搜索 word_id alt_spell_word_id 列。每当我想查看它的详细信息时,这个过程就会成为数据库中每个单词的对话位置。一种可能的解决方案是在 Words 表中创建一个额外的布尔列,用于跟踪单词是否具有替代拼写。这将指示我们是否应该在 Word详细信息表单中打开 Alternative Spellings 表时进行扫描。这是什么样子:

+---------+-----------+------------------+
| word_id | word      | has_alt_spelling |
+---------+-----------+------------------+
|     101 | ketchup   | yes              |
|     102 | catsup    | no               |
|     103 | catchup   | no               |
|     104 | moneyed   | yes              |
|     105 | monied    | no               |
|     106 | delicious | no               |
+---------+-----------+------------------+

我认为这是一个很好的设计,但正如我所说,我非常想听听你对此有何看法:问题/不是问题?你的解决方案?

2:另一个更严重的问题与主键有关。当然, word_id alt_spell_word_id 应该是复合主键的一部分。我们不希望表中有重复的行。我们都明白这一点。不是问题。但是,当我们尝试在 Words 表和 Alternative Spellings 表之间强制执行参照完整性时会发生什么(请参阅上面的屏幕截图)。一切都很好,除了现在我们可以将一个单词与一个不存在的单词的id相关联,并且数据库不会抱怨,例如, word_id 中的最后一条记录中有4个,这是是的,我们确实在 Words 表中有一个id为4的记录,但是没有办法对 alt_spell_word_id 列施加任何类型的约束。我们可以在那里放任何废话:

+---------+-------------------+
| word_id | alt_spell_word_id |
+---------+-------------------+
|       1 |                 2 |
|       1 |                 3 |
|       4 |                 5 |
|       4 |             34564 |
+---------+-------------------+

我认为这会破坏数据库模式的引用完整性,因此是一个严重的问题。你想提供什么样的解决方案?

3:此设计的另一个问题是,如果我们要从 Words 表中删除某个单词,删除将通过 Alternative Spellings 表级联并删除那里的所有相关记录都很好,但这里有一个问题:因为我们一致认为数据库中的不同单词实际上只能是一个拼写不同的单词,所以它们都应该与主要单词一起删除。但是,目前的情况不会发生。例如,如果我要删除 Words 表中的 ketchup ,则会删除 Alternative Spellings 表中的所有相关记录。精细。但我们真的得到两个悬空记录,追赶 catsup - 他们不能自己存在,因为他们是的一部分>番茄酱是主要词,但现在它已被删除:

+---------+-----------+
| word_id | word      |
+---------+-----------+
|       2 | catsup    |
|       3 | catchup   |
|       4 | moneyed   |
|       5 | monied    |
|       6 | delicious |
+---------+-----------+

+---------+-------------------+
| word_id | alt_spell_word_id |
+---------+-------------------+
|       4 |                 5 |
+---------+-------------------+

如果你想玩它,可以在这里the actual database(简化版)。

提前谢谢大家。

2 个答案:

答案 0 :(得分:0)

我认为我会使用另一个表定义word_spelling_group s的模型,因此对于每个可能与“ketchup”相同的单词,此表中的条目具有相同的值word_spelling_group为“番茄酱”的word_spelling_group值。

这样做的一个优点是,一个单词可以是多个拼写组的成员,以防它只在特定含义的上下文中有替代拼写(我为一个例子而努力)。

答案 1 :(得分:0)

1)对于1,如果你将索引添加到数据库,它可能不是一个大问题(因为你的单词然后加入以获得替代单词会很快) 。但是,如果子词只能有一个父词,那么您不需要额外的表:

单词表可以是:

$(document).on("keypress", ebClose);

对单词及其子项的查询将是:

+---------+-----------+------------------+
| word_id | word      | parent_word_id   |
+---------+-----------+------------------+
|     101 | ketchup   |                  |
|     102 | catsup    | 101              |
|     103 | catchup   | 101              |
|     104 | moneyed   |                  |
|     105 | monied    | 104              |
|     106 | delicious |                  |
+---------+-----------+------------------+

对单词和相关单词的查询,无论是否为子单词,都是:

select wordGroup.word 
from word w join word wordGroup on 
    (w.word_id = wordGroup.parent_word_id 
     or wordGroup.word_id = w.word_id) 
where w.word = {your_word};

2 这样做的正确方法是在表上放置外键约束(引用约束)。在我的1示例中,parent_word_id将具有返回到word(word_id)的引用约束。对于您的示例,alt_spell_word_id将具有返回字表和word_id的引用约束。然后,您可以对word_id和alt_spell_id的组合设置唯一约束。请参阅(关于访问限制):https://msdn.microsoft.com/en-us/library/bb177889(v=office.12).aspx

3 我认为删除主要单词在您的设计中存在含义问题。删除主要单词并保持分组是什么意思?从理论上讲,你必须做一系列的操作:1 - 决定一个新的主要词; 2 - 删除旧的。几乎所有设计都包括主要词语。

另一种选择是,没有主要词语,但要有群组。这会将db设计从主要单词和其他单词之间的一对多关系改为单词之间的多对多关系。在这种情况下,删除很容易,因为您只是将所有关联级联到word_groups表中的单词。

结果表将是:

字:

select wordGroup.word 
from word w join word wordGroup on 
    (w.word_id = wordGroup.parent_word_id 
    or wordGroup.word_id = w.word_id) 
where wordGroup.word_id = {your_word};

word_groups:

+---------+-----------+
| word_id | word      |
+---------+-----------+
|     101 | ketchup   |
|     102 | catsup    |
|     103 | catchup   |
|     104 | moneyed   |
|     105 | monied    |
|     106 | delicious |
+---------+-----------+

外键约束可以保护参照完整性,而索引可以快速查找。