Как зайти в Даркнет?!
25th January, 01:11
6
0
Как в tkinter из поля ввода Entry получить значение в одну переменную и обновить строку кнопкой, затем получить ещё одно введённое значение и затем сложить их. Ниже пример кода
21st July, 19:00
894
0
Программа, которая создает фейковые сервера в поиске игровых серверов CS 1.6 Steam
21st March, 17:43
948
0
Очень долго работает Update запрос Oracle
27th January, 09:58
913
0
не могу запустить сервер на tomcat HTTP Status 404 – Not Found
21st January, 18:02
905
0
Где можно найти фрилансера для выполнения поступающих задач, на постоянной основе?
2nd December, 09:48
938
0
Разработка мобильной кроссплатформенной военной игры
16th July, 17:57
1724
0
период по дням
25th October, 10:44
3955
0
Пишу скрипты для BAS только на запросах
16th September, 02:42
3720
0
Некорректный скрипт для закрытия блока
14th April, 18:33
4613
0
прокидывать exception в блоках try-catch JAVA
11th March, 21:11
4381
0
Помогите пожалуйста решить задачи
24th November, 23:53
6086
0
Не понимаю почему не открывается детальное описание продукта
11th November, 11:51
4350
0
Нужно решить задачу по программированию на массивы
27th October, 18:01
4396
0
Метода Крамера С++
23rd October, 11:55
4309
0
помогите решить задачу на C++
22nd October, 17:31
4002
0
Помогите решить задачу на python с codeforces
22nd October, 11:11
4492
0
Python с нуля: полное руководство для начинающих
18th June, 13:58
2599
0
Дебаты по дизайну: каковы хорошие способы хранения и управления версионными объектами?
Я намеренно оставляю это довольно расплывчатым на первый взгляд. Я ищу обсуждения и какие вопросы важны больше, чем я ищу трудные ответы.
Я нахожусь в середине разработки приложения, которое делает что-то вроде управления портфелем. Дизайн, который у меня есть до сих пор, - это
- Проблема: проблема, которую необходимо решить
- Решение: предлагаемое решение одной или нескольких проблем
- Отношение: отношение между двумя проблемами, двумя решениями или проблемой и решением. Далее разбивается на:
- Родитель-ребенок - своего рода категоризация / иерархия дерева
- Перекрытие-степень, в которой два решения или две проблемы действительно решают одну и ту же концепцию
- Адреса-степень, в которой проблема обращается к решению
Мой вопрос касается временной природы этих вещей. Проблемы возникают, а затем исчезают. Решения имеют ожидаемую дату разрешения, но она может быть изменена по мере их разработки. Степень взаимосвязи может меняться с течением времени по мере развития проблем и решений.
Итак, вопрос: каков наилучший дизайн для версирования этих вещей, чтобы я мог получить как текущую, так и историческую перспективу своего портфолио?
Позже: возможно, я должен сделать это более конкретным вопросом, хотя ответ @Eric Beard стоит того.
Я рассмотрел три проекта баз данных. Я буду достаточно каждого, чтобы показать свои недостатки. Мой вопрос: Что выбрать, или вы можете придумать что-то лучше?
1: проблемы (и отдельно, решения) являются самореферентными в управлении версиями.
table problems
int id | string name | text description | datetime created_at | int previous_version_id
foreign key previous_version_id -> problems.id
Это проблематично, потому что каждый раз, когда я хочу новую версию, я должен дублировать всю строку, включая этот длинный столбец description .
2: Создайте новый тип отношений: версия.
table problems
int id | string name | text description | datetime created_at
Это просто перемещает отношения из таблиц проблем и решений в таблицу отношений. Та же проблема дублирования, но, возможно, немного "cleaner", так как у меня уже есть абстрактная концепция отношений.
3: Используйте более Субверсионную структуру; переместите все атрибуты проблемы и решения в отдельную таблицу и версируйте их.
table problems
int id
table attributes
int id | int thing_id | string thing_type | string name | string value | datetime created_at | int previous_version_id
foreign key (thing_id, thing_type) -> problems.id or solutions.id
foreign key previous_version_id -> attributes.id
Это означает, что для загрузки текущей версии проблемы или решения я должен извлечь все версии атрибута, отсортировать их по дате, а затем использовать самую последнюю. Это может быть не так уж и страшно. Что кажется мне действительно плохим, так это то, что я не могу проверить эти атрибуты в базе данных. Этот столбец value должен быть свободным текстом. Я могу сделать столбец name ссылкой на отдельную таблицу attribute_names , которая имеет столбец type ,но это не заставляет правильный тип в таблице attributes .
еще позже: ответ на комментарии @Eric Beard о внешних ключах с несколькими таблицами:
Увы, то, что я описал, является упрощенным: есть только два типа вещей (проблемы и решения). На самом деле у меня есть около 9 или 10 различных типов вещей, поэтому у меня будет 9 или 10 столбцов внешних ключей под вашей стратегией. Я хотел использовать наследование одной таблицы, но эти вещи имеют так мало общего, что было бы крайне расточительно объединять их в одну таблицу.
Хм, похоже на этот сайт...
Что касается дизайна базы данных, система управления версиями, такая как SVN, где вы никогда не делаете никаких обновлений, просто вставляете (с номером версии), когда все меняется, может быть тем, что вам нужно. Это называется MVCC, управление многозначным параллелизмом. А wiki-еще один хороший пример этого.
@Gaius
foreign key (thing_id, thing_type) -> problems.id or solutions.id
Будьте осторожны с этими типами внешних ключей "multidirectional". Мой опыт показал, что производительность запросов сильно страдает, когда ваше условие соединения должно проверить тип, прежде чем выяснять, к какой таблице присоединиться. Это не кажется таким элегантным, но обнуляется
problem_id and solution_id
будет работать намного лучше.
Конечно, производительность запросов также будет страдать с дизайном MVCC, когда вам нужно добавить проверку, чтобы получить последнюю версию записи. Компромисс заключается в том, что вам никогда не придется беспокоиться о конкуренции с обновлениями.
Как вы думаете об этом:
проблемы таблицы
int id / имя строки / текстовое описание / datetime created_at
таблица problems_revisions
пересмотр инт | инт код | наименование строки | текстовое описание | datetime created_at
идентификатор внешнего ключа - > problems.id
Перед обновлением необходимо выполнить дополнительную вставку в таблицу ревизий. Эта дополнительная вставка быстро, однако, это то, что вы должны заплатить за
- эффективный доступ к текущей версии-выберите проблемы как обычно
- схема, которая интуитивно понятна и близка к реальности, которую вы хотите смоделировать
- соединения между таблицами в схеме сохраняют эффективность
- используя номер версии для каждой транзакции шины, вы можете выполнять управление версиями над записями таблицы, как SVN делает над файлами.
Я полагаю, что есть
Вариант 4: гибрид
Переместите атрибуты common Thing в таблицу с одним наследованием, а затем добавьте таблицу custom_attributes . Это упрощает использование внешних ключей, уменьшает дублирование и обеспечивает гибкость. Это не решает проблемы типобезопасности для дополнительных атрибутов. Это также добавляет немного сложности, так как есть два способа для вещи, чтобы иметь атрибут сейчас.
Если description и другие большие поля остаются в таблице вещей, это также не решает проблему дублирования пространства.
table things
int id | int type | string name | text description | datetime created_at | other common fields...
foreign key type -> thing_types.id
table custom_attributes
int id | int thing_id | string name | string value
foreign key thing_id -> things.id
Это хорошая идея, чтобы выбрать структуру данных, которая делает общие вопросы, которые вы задаете модели легко ответить. Скорее всего, вы заинтересованы в текущей позиции большую часть времени. Иногда вам захочется углубиться в историю для конкретных проблем и решений.
У меня были бы таблицы для проблемы, решения и отношений, которые представляют текущую позицию. Там также будет таблица problem_history , solution_history и т. д. Это будут дочерние таблицы проблем, но также содержат дополнительные столбцы для VersionNumber и EffectiveDate . Ключ будет ( ProblemId, VersionNumber).
Когда вы обновляете проблему, вы записываете старые значения в таблицу problem_history . Поэтому запросы на момент времени возможны, поскольку вы можете выбрать запись problem_history , которая действительна as-at на определенную дату.
Там, где я делал это раньше, я также создал представление UNION problem и problem_history , поскольку это иногда полезно в различных запросах.
Вариант 1 затрудняет запрос текущей ситуации, так как все ваши исторические данные смешиваются с текущими данными.
Вариант 3 будет плохим для производительности запросов и неприятным для кода, поскольку вы будете получать доступ к большому количеству строк для того, что должно быть просто простым запросом.