Структура данных «многие ко многим» в Python - PullRequest
8 голосов
/ 21 августа 2010

У меня есть набор данных о книгах и авторах с отношением многих ко многим.

Существует около 10 ^ 6 книг и 10 ^ 5 авторов, в среднем по 10 авторов на книгу.

Мне нужно выполнить ряд операций над набором данных, например подсчет количества книг каждого автора или удаление всех книг определенного автора из набора.

Какая будет хорошая структура данных, которая обеспечит быструю обработку?

Я надеюсь на какой-нибудь готовый модуль, который может предоставлять методы в соответствии с:

obj.books.add(book1)

# linking
obj.books[n].author = author1
obj.authors[m].author = book1

# deleting
obj.remove(author1) # should automatically remove all links to the books by author1, but not the linked books

Я должен уточнить, что я предпочитаю не использовать для этого базу данных, а делать все это в памяти.

Спасибо

Ответы [ 2 ]

17 голосов
/ 21 августа 2010

sqlite3 (или любая другая хорошая реляционная БД, но sqlite поставляется с Python и удобнее для такого небольшого набора данных) кажется правильным подходом для вашей задачи.Если вы не хотите изучать SQL, SQLAlchemy является, так сказать, популярной «оболочкой» для реляционных БД, позволяющей вам работать с ними на любом из нескольких уровней абстракции по вашему выбору.

И «делать все это в памяти» - это совсем не проблема (это просто глупо 1009 *, так как вы будете без необходимости оплачивать накладные расходы на чтение всех данных, где-то более настойчиво, на каждом из них).и каждый запуск вашей программы при сохранении БД в файле на диске избавит вас от этих накладных расходов - но это другая проблема ;-).Просто откройте свою базу данных sqlite как ':memory:', и вот вы - новая, новая реляционная БД, живущая полностью в памяти (только на время вашего процесса), никакой диск не задействован в процедуре вообще .Так почему бы и нет? -)

Лично я бы использовал SQL непосредственно для этой задачи - он дает мне превосходный контроль над тем, что происходит, и легко позволяет мне добавлять или удалять индексы для настройки производительности и т. Д.Вы бы использовали три таблицы: таблицу Books (идентификатор первичного ключа, другие поля, такие как Title & c), таблицу Authors (идентификатор первичного ключа, другие поля, такие как Name & c) и многозначную-много таблицы отношений ", скажем, BookAuthors, всего с двумя полями BookID и AuthorID и одной записью на соединение с книгой автора.

Два поля таблицы BookAuthorsизвестный как «внешние ключи», относящийся соответственно к полям идентификаторов Книг и Авторов, и вы можете определить их с помощью ON DELETE CASCADE, чтобы записи, относящиеся к книге или автору, которые были удалены, автоматически удалялись по очереди - примервысокий семантический уровень, на котором даже «голый» SQL позволяет работать, и никакая другая существующая структура данных не может сравниться с ним.

2 голосов
/ 21 августа 2010

Я надеюсь на какой-нибудь готовый модуль, который может предоставлять методы в соответствии с:

Поскольку это действительно работает, что еще вам нужно?

У вас есть определение класса Book и Author. У вас также есть ассоциация авторов книг для отношений. Методы, необходимые для управления добавлением / изменением / удалением, - это всего лишь несколько строк кода.

Создание больших старых словарей объектов ассоциации авторов, книг и авторов-книг.

Используйте shelve для хранения всего этого.

Готово.

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