Как я могу структурировать свои таблицы базы данных таким образом, чтобы их порядок можно было изменить в любое время? - PullRequest
0 голосов
/ 15 марта 2020

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

Проблема, с которой я столкнулся, заключается в том, что я не могу изменить порядок заметок или вставить новую страницу где-нибудь. Мое текущее решение состоит в том, чтобы иметь 2 идентификатора - один является основным индексом (ID), а другой - относительным идентификатором (RID). Чтобы изменить порядок строк, я просто изменяю RID этой строки, а затем сортирую строки по RID при их отображении.

ID | RID | page_title | page_content
01 | 01  | Hello      | Hello world
02 | 02  | Goodbye    | See ya

Это работает, когда у меня очень мало страниц, но если бы у меня было 100 страниц, и я хотел бы переставить или вставить новую строку посередине, мне пришлось бы менять RID для каждого строка ниже, где было сделано изменение.

Как правильно структурировать мою таблицу так, чтобы ее можно было легко переставить или вставить позже? Я знаком с MySQL с использованием PhpMyAdmin и SQLite с использованием SQLAlchemy.

Извините, если раньше об этом спрашивали, сложно сформулировать вопрос в поиске в Google, я продолжал получать неуместные результаты. Заранее спасибо!

Ответы [ 2 ]

1 голос
/ 15 марта 2020

Есть много способов сделать это. Одним простым способом было бы рассматривать страницы как связанный список. Вместо столбца заказа используйте столбец prior, который указывает (FK) на страницу, предшествующую этим страницам.

Например, начиная со страниц в порядке ab- c -d:

id, page name, prior
1, a, null
2, b, 1
3, c, 2
4, d, 3
5, e, 4

Чтобы переместить страницу «b» на страницу «d», вам необходимо:

(1) изменить c до 1

(2) изменить b до 4

(3) измените e до 2

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

id, page name, prior
1, a, null
2, b, 4
3, c, 1
4, d, 3
5, e, 2

Будет необходимо одинаковое количество операций (3 для односвязного списка) независимо от общего количества страниц.

Убедитесь, что проверить вашу реализацию для перемещения первой страницы (prior = null), так как это особый случай.

0 голосов
/ 15 марта 2020

Я только что подумал о другом решении, но я не знаю, с какими недостатками это может произойти.

Сохраните заказ в виде списка идентификаторов (т.е. 1, 2, 3, 4, 5 ) в отдельную таблицу вместе с идентификатором списка.

(Pages Table)
ID, page, listID
1, a, 1
2, b, 1
3, c, 1
4, d, 1
5, e, 1

(Lists Table)
ListID, list_sequence
1, (1,2,3,4,5)

Каждый раз, когда меняется заказ, сохраняйте новый заказ в таблице списков. При извлечении данных для отображения сначала извлеките list_sequence из таблицы списков, затем выполните что-то вроде

for id in list_sequence:
    Pages.query.get(id)
    // display the row

Таким образом, строки будут извлекаться последовательно в соответствии с указанным порядком. Каждая перестановка будет записывать в базу данных только один раз.

Пожалуйста, дайте мне знать, если есть веская причина не использовать этот метод!

Редактировать: столбец list_sequence будет сохранен как строка.

Редактировать 2: Это добавит еще одну операцию для каждой вставки. Новая строка должна быть вставлена, а затем также должна быть обновлена ​​list_sequence. Будет ли это очень существенной разницей в скорости?

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