【问题标题】:How to represent an array of arrays in a relational database如何在关系数据库中表示数组数组
【发布时间】:2012-02-18 03:26:53
【问题描述】:

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

  • '非常不称职的出租车司机'
    1. Extra-₁  ordinari₂  -ly₃
    2. in-₁  胜任 2
    3. taxi-₁  drive₂  -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 );

我通常更喜欢干净的解决方案,但这里的干净解决方案给人一种笨拙的感觉。顺便说一下(Django),我正在尝试使用 Web 框架 ORM 来做到这一点。

【问题讨论】:

  • 老实说,我的 2cts 是关系数据库对于 NLP(自然语言处理)来说是一个糟糕的起点。否则你的第二个设计是有意义的(不知何故)。
  • 一些关系型数据库(如Oracle)有嵌套表的概念(orafaq.com/wiki/NESTED_TABLE),可以用来实现数组的数组。
  • 是的,有些数据库支持数组类型; MongoDB 允许类似的东西。但考虑到我正在使用的框架,我正在寻找一种技术含量更低/真正的关系解决方案(MySQL 或 PostgreSQL 可以)。

标签: django database database-design relational-database


【解决方案1】:

您的第二个解决方案在技术上是正确的。您感到的混乱实际上不是由于数组数组问题,而是由于您在句子和单词之间以及语素和单词之间存在多对多关系这一事实。 (任何给定的句子可以是一个或多个单词,任何单词都可以是一个或多个句子的一部分。)这是 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()

诚然,我只是在这里输入了这些模型,但这应该会让您接近需要的位置。

编辑:引入了词模型。

【讨论】:

  • 您的 Django 模型似乎与 OP 的第一个和第二个模型有点不同。您的模型没有Word 关系。
  • 对于第一个设计,没有 word 关系在我的情况下实际上可以工作。谢谢!但我也在提前考虑:一旦“单词”概念得到充实,它肯定需要自己的表格。
【解决方案2】:

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

如果您碰巧使用 Oracle,则可以通过将用于“清洁”的第二种设计与提高性能的 materialized views 结合起来,让您的蛋糕也吃起来。

【讨论】:

  • 第一种设计的另一个缺点是你不能存储一个单词而不存储它所属的句子。
【解决方案3】:

如果我们将所涉及的数据结构作为数组values的数组,则有一个简单的替代解决方案,即干净高效、并且使用起来很直观

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

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

这种设计的缺点是多次出现的数组项,如extraordinari-ly中的-ly,存储的次数很多数据库中的次数,每次出现一次。不可能将附加数据与所有 -ly 语素相关联。

【讨论】:

    猜你喜欢
    • 2017-08-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-04
    • 1970-01-01
    相关资源
    最近更新 更多