Разработка базы данных Django: многие-ко-многим, внешний ключ или нет? - PullRequest
2 голосов
/ 16 января 2012

Нубский вопрос. Я собираю свою первую базу данных и сталкиваюсь со следующей проблемой дизайна: у меня есть класс, который определяет книгу (например, ее название) и класс, который определяет страницу (например, это дизайн).

Таблица для учебника выглядела бы так:

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

Теперь, поскольку каждая страница уникальна и не может быть повторно использована в другой книге, я не могу использовать отношение «многие ко многим» для «Страниц». Я мог бы использовать Foreign-Key для связи двух таблиц, то есть связать SAMPLE1-UUID таблицы книг с SAMPLE1-UUID таблицы страниц. Преимущество этого состоит в том, что вы не создаете одну и ту же запись дважды.

Однако мне не нравится идея иметь фиксированное количество строк для моих страниц. В приведенном выше примере для класса Book мне нужно будет определить определенный набор страниц, например, PAGE1, PAGE2, PAGE3, PAGE4, ​​... PAGE99. В идеале все, что мне нужно, это гибкий список страниц для моего класса книги, например:

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

Pages будет простым CharField, а его содержимое будет списком. Но тогда у меня возникает проблема, заключающаяся в том, что две таблицы больше не связаны и что мне придется создавать каждую запись дважды (т.е. мне нужно будет ввести SAMPLE1-UUID как в таблице страниц, так и в таблице книг).

Есть ли другой способ создать эту базу данных? Спасибо за любое предложение!

Ответы [ 3 ]

5 голосов
/ 16 января 2012

Я предлагаю, чтобы у вас не было страниц в виде столбцов:

Таблица для учебника будет выглядеть так, только с информацией о книге:

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 не повторялись, например, но это может быть хорошим началом.

3 голосов
/ 16 января 2012

Я бы сделал это так:

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

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

Я не понимаю пример таблицы вашей книги: вам нужен столбец для страницы1 и другой столбец для страницы2?Это выглядит очень странно.

1 голос
/ 16 января 2012

Вы неправильно поняли, как работает внешний ключ. Это не «фиксированное количество строк», а наоборот.

Как показывает Геттли в своем ответе, поле ForeignKey является отношением один-ко-многим, определенным со стороны «многие». То есть, когда ForeignKey определен на странице, указывающей на книгу, каждая страница имеет одну книгу, но в книге столько страниц, сколько вам нужно.

Итак, используя Django ORM, если у вас есть объект книги и вы хотите получить все его страницы, вы просто делаете my_book.page_set.all().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...