I have a data set of books and authors, with a many-to-many relationship.
There are about 10^6 books and 10^5 authors, with an average of 10 authors per book.
I need to perform a series of operations on the data set, such as counting the number of books by each author or deleting all books by a certain author from the set.
What would be a good data structure that will allow fast handling?
I'm hoping for some ready made module that can provide methods along the lines of:
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
I should clarify that I prefer not to use a database for this, but to do it all in memory.
Thanks
sqlite3 (или любая другая хорошая реляционная БД, но sqlite
поставляется с Python и удобнее для такого достаточно небольшого набора данных) кажется правильным подходом для вашей задачи. Если вы не хотите изучать SQL, SQLAlchemy - это популярная "обертка" над реляционными БД, так сказать, позволяющая работать с ними на любом из нескольких различных уровней абстракции по вашему выбору.
И "делать все это в памяти" - совсем не проблема (это глупо, имейте в виду, поскольку вы будете без нужды оплачивать накладные расходы на чтение всех данных из более постоянного места при каждом запуске вашей программы, в то время как хранение БД в дисковом файле избавит вас от этих накладных расходов - но это уже другой вопрос; -). Просто откройте вашу sqlite базу данных как ':memory:'
и вот вы уже здесь - свежая, новая реляционная БД, живущая полностью в памяти (только на время вашего процесса), никакого диска в процедуре вообще не задействовано. Так почему бы и нет?)
Лично я бы использовал SQL непосредственно для этой задачи - он дает мне отличный контроль над тем, что именно происходит, и позволяет легко добавлять или удалять индексы для настройки производительности и т.д. Вы будете использовать три таблицы: таблицу Books
(первичный ключ ID, другие поля, такие как Title &c), таблицу Authors
(первичный ключ ID, другие поля, такие как Name &c), и "таблицу отношений "многие-ко-многим", скажем BookAuthors
, всего с двумя полями, BookID
и AuthorID
, и одной записью на связь автор-книга.
Два поля таблицы BookAuthors
являются так называемыми "внешними ключами", относящимися соответственно к полям ID книг и авторов, и вы можете определить их с помощью ON DELETE CASCADE
, так что записи, относящиеся к книге или автору, которые удаляются, автоматически удаляются в свою очередь - пример высокого семантического уровня, на котором позволяет работать даже "голый" SQL, с которым не может сравниться ни одна другая существующая структура данных.
Я надеюсь на какой-нибудь готовый модуль, который может предоставлять методы следующего вида:
Поскольку это действительно работает, что еще вам нужно?
У вас есть определение классов Book и Author. У вас также есть ассоциация "Книга-Автор" для взаимоотношений. Методы, необходимые для управления добавлением / изменением / удалением, представляют собой всего несколько строк кода.
Создавать большие старые словари объектов ассоциаций Авторы, Книги и Автор-Книга.
Используйте полку
, чтобы хранить все это.
Готово.