Нечетный дизайн базы данных, руководство по потребностям
Вероятно, я думаю об этом неправильно, но здесь идет.
Компьютер начинает выплескивать беспорядочные случайные числа между 11111111111111111111 и 99999999999999999999, в линейной строке:
- Иногда компьютер добавляет число к одному концу строки.
- Иногда компьютер добавляет номер на другой конец строки.
- Каждое число имеет число, которое приходит или будет раньше.
- Каждый номер имеет число, которое приходит или будет появляться после.
- Не все числа уникальны, многие, но не большинство, повторяются.
- Компьютер никогда не прекращает выплескивать номера.
Когда я записываю все эти числа, мне нужно уметь давать обоснованное предположение в любой момент времени:
-
Если это второй раз, когда я видел номер, я должен знать, какое число предшествовало ему в строке в последний раз.
-
Если он появился более двух раз, я должен знать вероятность/частоту предшествующих ему цифр.
-
Если это второй раз, когда я видел число, я также должен знать, какое число пришло после него в строке в последний раз.
-
Если он появился более двух раз, я должен знать вероятность/частоту чисел, следующих за ним.
Как я могу структурировать таблицы в базе данных MySQL для хранения всех этих чисел? Какой двигатель я использую и почему? Как сформулировать свои запросы? Мне нужно знать быстро, но способность также важна, потому что когда вещь перестанет выплевывать их?
Мой плохо продуманный план:
2 Таблицы:
1. Unique ID/#
2. #/ID/#
Мои мысли:
Уникальный идентификатор почти всегда будет короче, чем число = быстрее совпадение.
Цифры повторяются = меньше строк идентификаторов = быстрее выполняется сравнение.
Select * in table2 where id=(select id in table1 where #=?)
ИЛИ
3 Таблицы:
1. Unique ID/#
2. #/ID
3. ID/#
Мои мысли:
Если мне нужно только left/before или нужно только после/справа, я уменьшу размер второго запроса.
SELECT # IN table2(or 3) WHERE id=(SELECT id IN table1 WHERE #=?)
ИЛИ
1 Таблица:
1. #/#/#
Мысли:
Меньше запросов = меньше времени.
SELECT * IN table WHERE col2=#.
Я потерялся....:( Каждый номер имеет четыре атрибута, то, что предшествует + частоте, и то, что приходит после + частоты.
Неужели мне лучше подумать об этом? Если я храню и увеличиваю частоту в таблице, я удаляю повторение и тем самым ускоряю свои запросы? Я изначально думал, что если я сохраню все случаи, было бы быстрее изобразить частоту программно.......
Такие простые данные, но я просто не знаю, как работают базы данных, которые более эффективны.
В свете недавнего комментария я хотел бы добавить немного информации о реальной проблеме: у меня строка неопределенной длины. Я пытаюсь сохранить в этой строке таблицу частот цепи Маркова различных символов или фрагментов символов.
Для любой точки в строке мне нужно знать вероятность следующего состояния и вероятность предыдущего состояния.
Я ожидаю ввода пользователя, основываясь на тексте и прошлом пользовательском вводе. Основное отличие по сравнению с другими приложениями, которые я видел, это то, что я иду дальше по цепочке, больше состояний в данный момент времени, и мне нужны данные частоты, чтобы предоставить несколько возможностей.
Я надеюсь, что это еще раз прояснит картину. Я не хотел вникать в проблему, потому что в прошлом я создал вопросы, которые недостаточно специфичны, чтобы получить конкретный ответ.
Кажется, это немного лучше. Мой основной вопрос с этим решением: Предоставляет ли "ключ" (первые несколько символов состояния) увеличение скорости системы? i.e для state_key, затем запрашивать только результаты этого запроса для полного состояния?
Table 1:
name: state
col1:state_id - unique, auto incrementing
col2:state_key - the first X characters of the state
col3:state - fixed length string or state
Table 2:
name: occurence
col1:state_id_left - non unique key from table 1
col2:state_id_right - non unique key from table 1
col3:frequency - int, incremented every time the two states occur next to each other.
QUERY TO FIND PREVIOUS STATES:
SELECT * IN occurence WHERE state_id_right=(SELECT state_id IN state WHERE state_key=? AND state=?)
QUERY TO FIND NEXT STATES:
SELECT * IN occurence WHERE state_id_left=(SELECT state_id IN state WHERE state_key=? AND state=?)
Ответы
Ответ 1
Я не знаком с Марковскими цепями, но вот попытка ответить на вопрос. Примечание. Чтобы упростить ситуацию, позвольте каждой строке чисел указать "состояние".
Прежде всего, я представляю себе такую таблицу
Table states:
order : integer autonumeric (add an index here)
state_id : integer (add an index here)
state : varchar (?)
: просто используйте последовательный номер (1,2,3,..., n), это упростит поиск предыдущего или следующего состояния.
state_id: уникальный номер, связанный с состоянием. Например, вы можете использовать число 1 для представления состояния "1111111111... 1" (независимо от длины последовательности). Важно то, что повторение штата должно использовать тот же state_id, который использовался ранее. Вы можете сформулировать state_id на основе строки (возможно, вычитая число). Конечно, state_id имеет смысл только в том случае, если число возможных состояний совпадает с полем MySQL int.
state: это строка чисел 11111111... 1 'to' 99999999... 9 '... Я предполагаю, что это можно сохранить только как строку, но если она вписывается в целое число/число столбец, вы должны попробовать его, так как вполне возможно, что вам не нужен state_id
Точка state_id заключается в том, что поиск числа быстрее, чем поиск текстов, но всегда есть компромиссы, когда дело доходит до профиля производительности... и определяют ваши узкие места, чтобы принимать более конструктивные решения.
Итак, как вы смотрите предыдущее появление состояния S_i?
"SELECT order, state_id, состояние FROM state WHERE state_id =", а затем присоедините get_state_id (S_i), где get_state_id идеально использует формулу для генерации уникального идентификатора для состояния.
Теперь, с порядком - 1 или заказом + 1, вы можете получить доступ к соседним состояниям, выдающим дополнительный запрос.
Далее нам нужно отслеживать частоту различных вхождений. Вы можете сделать это в другой таблице, которая может выглядеть так:
Table state_frequencies:
state_id integer (indexed)
occurrences integer
И только добавьте записи, когда вы получите числа.
Наконец, вы можете иметь таблицы для отслеживания частоты для соседних состояний:
Table prev_state_frequencies (next_state_frequencies is the same):
state_id: integer (indexed)
prev_state_id: integer (indexed)
occurrences: integer
Вы сможете вывести вероятности (я думаю, это то, что вы пытаетесь сделать), просмотрев количество вхождений состояния (в state_frequencies) и количество вхождений его состояния-предшественника (в prev_state_frequencies).
Я не уверен, правильно ли я понял вашу проблему, но если это имеет смысл, я предполагаю, что у меня есть.
Надеюсь, что это поможет,
AH
Ответ 2
Мне кажется, что Марковская цепь конечна, поэтому сначала я бы начал с определения предела цепочки (т.е. 26 символов с x количеством заполняемых пробелов), тогда вы можете рассчитать общее количество возможных комбинаций. для определения вероятности некоторой компоновки символов математика, если я правильно помню:
x = ((C) (C)) (P)
где
C = количество возможных символов и
P = общие потенциальные исходы.
это тонна данных для хранения и создания процедур для фильтрации данных может оказаться бесконечной задачей.
- > если вы используете автоматически увеличивающийся id в своей таблице, вы можете запросить таблицу и использовать preg_match для проверки нового результата по сравнению с предыдущими результатами, а затем вставить количество итоговых совпадений с новым результатом в таблицу, это также позволит вам выполнить запрос предыдущие результаты, чтобы увидеть, что было раньше, это должно дать вам общее представление о шаблоне в результатах, а также общую базу статистической значимости и генерации нового алгоритма.