Django数据库设计:多对多,外键,还是两者都没有?

时间:2012-01-16 16:02:11

标签: database django postgresql django-models

一个菜鸟问题。我正在整理我的第一个数据库并遇到以下设计问题:我有一个定义书籍的类(例如它的标题)和定义页面的类(例如它的设计)。

课堂书的表格如下:

Title        | PAGE1        | PAGE2        | PAGE3
Book-One     | SAMPLE1-UUID | SAMPLE2-UUID | SAMPLE3-UUID
Book-Two     | SAMPLE4-UUID | SAMPLE5-UUID | SAMPLE6-UUID

班级页面的表格:

UUID         | FONT         | CONTENTS etc.
SAMPLE1-UUID | Times        | Example
SAMPLE2-UUID | Arial        | Example Two
SAMPLE3-UUID | Verdena      | Example Three

现在,由于每个页面都是唯一的,并且无法在另一本书中重复使用,因此我不能对Pages使用多对多关系。我可以使用Foreign-Key来链接这两个表,即将Books表的SAMPLE1-UUID链接到Pages表的SAMPLE1-UUID。这样做的好处是不会两次创建相同的条目。

但是,我不喜欢为我的页面设置固定数量的行。在上面的Book类示例中,我必须定义一组特定的页面,如PAGE1,PAGE2,PAGE3,PAGE4,... PAGE99。理想情况下,我需要的只是我的书类的灵活页面列表,如下所示:

Name         | Pages
Book-One     | "SAMPLE1-UUID, SAMPLE2-UUID"
Book-Two     | "SAMPLE4-UUID, SAMPLE5-UUID, SAMPLE6-UUID"

页面将是一个简单的CharField,其内容将是一个列表。但后来我遇到了这两个表不再链接的问题,而且我必须两次创建每个条目(即我必须在页面和书籍表中输入SAMPLE1-UUID)。

有没有其他方法可以设计这个数据库?谢谢你的任何建议!

3 个答案:

答案 0 :(得分:5)

我建议您不要将这些页面作为列:

课本书的表格看起来只有书本信息:

Title        | ISBN         
Book-One     | XXXXXXXXXXXX 
Book-Two     | YYYYYYYYYYYY 

班级页面的表格:

BOOKID       |PAGE_NUM | FONT         | CONTENTS
1            |1        | Times        | Example
1            |2        | Arial        | Example Two
2            |1        | Verdena      | Example Three

您的班级设计看起来像:

class Book(models.Model):
    title = models.CharField(max_length=100)
    isbn = models.CharField(max_length=100)

class Page(models.Model):
    book = models.ForeignKey(Book)
    page_num = models.IntegerField()
    font = models.charField(max_length=100)
    content = models.TextField()

你可以继续进行约束,以便书籍和page_num不会重复,但这可以是一个好的开始。

答案 1 :(得分:3)

我会这样做:

class Book(models.Model):
    name=models.CharField(max_length=....)

class Page(models.Model):
    book=models.ForeignKey(Book)
    number=models.PositiveIntegerField()

我不明白你的书表示例:你想要第1页的列和第2页的其他列吗?这看起来很奇怪。

答案 2 :(得分:1)

你误解了外键是如何工作的。它不是“固定数量的行” - 实际上恰恰相反。

正如guettli在他的回答中所示,ForeignKey字段是一对多的关系,在“很多”方面定义。也就是说,如果在页面上定义的ForeignKey指向Book,则每个页面都有一本书,但是书籍的页面数量可以与您一样多。

所以,使用Django ORM,如果你有一个书籍对象并想要获得它的所有页面,你只需要my_book.page_set.all()