如何在关系数据库中表示数组数组

时间:2012-01-24 21:22:14

标签: django database database-design relational-database

我需要为以下问题设计数据库架构。考虑一些示例短语的简化语法“分析”:

  • '非常无能的出租车司机'
    1. 特₁ordinari₂-ly₃
    2. 在-₁competent₂
    3. 滑行₁driv₂-er₃

在这个模型中,句子由一个单词数组组成,单词单词部分/语素的数组组成。关系数据库 - 正如我所知,众所周知 - 对阵列数组不太满意。

我看到两种解决方案,我不确定如何做出正确的决定。 第一个“脏”解决方案:单个中间表,用于将句子与语素链接,并存储数组索引。列中有很多相同的条目。

CREATE TABLE word (           -- pseudo-SQL
  sentence_id FOREIGN KEY,
  sentence_order INTEGER,
  morpheme_id FOREIGN KEY,
  morpheme_order INTEGER );

第二个'干净'解决方案:三个(!)中间表,使用起来可能既慢又不舒服?请注意 word 表如何仅提供要使用的两个外键表的ID。

CREATE TABLE sentence_word (
  sentence_id FOREIGN KEY,
  word_id FOREIGN KEY,
  order INTEGER );
CREATE TABLE word ( id );
CREATE TABLE morpheme_word (
  morpheme_id INTEGER FOREIGN KEY,
  word_id INTEGER FOREIGN KEY
  order INTEGER );

我通常更喜欢干净的解决方案,但这里干净的解决方案有一种愚蠢的感觉。顺便说一句,我正试图用网络框架ORM(Django)来做这件事。

3 个答案:

答案 0 :(得分:2)

您的第二个解决方案是技术上正确的解决方案。你感觉到的kludge实际上并不是由于数组问题,而是因为你在句子和单词之间以及语素和单词之间存在多对多的关系。 (任何给定的句子可以是一个或多个单词,任何单词都可以是一个或多个句子的一部分。)这是一个正常的kludge,它是SQL的一个(不幸的?)副作用。

既然你提到了django,那么django试图用many-to-many fields为你抽象一些。

我认为作为你的django的基本模型,你正在寻找这样的东西:

class Sentence(models.Model):
    words = models.ManyToManyField(Words, through=SentenceWord)

class Word(models.Model):
    morphenes = models.ManyToManyField(Morphene, through=MorpheneWord)

class Mophene(models.Model):
    pass


#--- Intermediate Tables ------------
class SentenceWord(models.Model):
    sentence = models.ForeignKey(Sentence)
    word = models.ForeignKey(Word)
    position = models.IntegerField()

class MorpheneWord(models.Model):
    word = models.ForeignKey(Word)
    morphene = models.ForeignKey(Morphene)
    position = models.IntegerField()

不可否认,我只是在这里输入了这些模型,但这应该让你接近需要的位置。

编辑:引入Word模型。

答案 1 :(得分:1)

在第一个设计中你很难执行正确的语素顺序,因此我喜欢第二个设计更好。但是,如果性能问题,第一个设计可能允许您减少JOINing。

如果你碰巧使用甲骨文,你也可以将你的蛋糕吃掉,将第二种“清洁度”设计与materialized views结合起来,以提高性能。

答案 2 :(得分:0)

如果我们将数据结构作为数组的数组包含在内,那么有一个简单的替代解决方案 clean 高效,并且直观地使用

CREATE TABLE Sentence (...);
CREATE TABLE Word     ( sentence_id FOREIGN KEY,
                        order INTEGER );
CREATE TABLE Morpheme ( word_id FOREIGN KEY,
                        order INTEGER );

这只是一对一的关系,两次。 (使用Django的ORM,您可以简单地说word.sentence来访问Word实例所属的句子,或者sentence.word_set.order_by('order')来获取某个句子中有序的单词集。)

此设计的缺点是多次出现的数组项,例如 extraordinari-ly 中的 -ly ,存储了很多数据库中的时间,每次出现一次。无法将其他数据与所有 -ly 语素相关联。