Приложение DB для синхронизации с сервером, вопросы по основным ключам, несколько таблиц и экономия места на диске - PullRequest
0 голосов
/ 22 октября 2018

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

Сейчас мои очень грубые таблицы выглядят примерно так:


Таблица USER сервера

  • USER_ID (INT PRIMARY KEY AUTOINCREMENT)
  • LAST_UPDATE- отметка времени с последним обновлением любого ввода данных
  • EMAIL
  • PASSWORD - соленое и хэшированное

Таблица ввода данных сервера

  • SERVER_ENTRY_ID (INT PRIMARY KEY AUTOINCREMENT) - будет уникальным для всех устройств
  • USER_ID (INT) - из пользовательской таблицы сервера
  • LAST_UPDATE - отметка времени с момента последнего обновления этой записи данных
  • Columns_For_Actual_Data ...

Таблица ввода данных клиентского приложения

  • ROW_ID (INT PRIMARY KEY AUTOINCREMENT) - используется только для локальных операций базы данных приложения, не используется совместно
  • SERVER_ENTRY_ID (INT) - это уникальный идентификатор записи данных сервера, полученный с сервера при добавлении на сервер
  • LAST_UPDATE - отметка времени с последнего времени, когда эта запись данных была локально в приложении
  • Columns_For_Actual_Data ...

Вопросы

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

  1. Можно ли использовать первичный ключ INT с автоинкрементом (PK) дляполезная информация, такая как идентификатор пользователя или идентификатор ввода данных?Я слышал, что это не очень хорошая практика, но я также видел примеры, когда PK используется для полезной информации.Есть ли опасения, что было бы сложно перенести строки в разные таблицы или базы данных, если бы мне это понадобилось?SERVER_ENTRY_ID будет таким же на сервере, как и на всех устройствах, которые синхронизируются с этим сервером.Альтернативная идея заключается в использовании UUID для SERVER_ENTRY_ID, но они не имеют автоинкрементации, поэтому я думаю, что поиск будет медленнее, а также займет гораздо больше места в БД (16-байтовый двоичный объект).

  2. ЕслиТаблицы ввода данных могут быть очень большими на сервере. Стоит ли вместо этого создавать несколько таблиц ввода данных?Например, user_id 0-9999 может использовать Table1, user_id 10000 - 19999 будет использовать Table2 и т. Д. Кроме того, хранение всех данных пользователя в одной таблице сделает поиск всех данных для одного пользователя быстрее, чем отдельных таблиц.

  3. Допустим, у меня есть таблица ввода данных с 5 столбцами INT и 3 столбцами DOUBLE, которые используются для хранения фактических данных.Также допустим, что эти 8 столбцов нужны только вместе и никогда не ищутся в предложении WHERE с запросами MYSQL.Давайте также скажем, что эти 8 столбцов часто имеют 0 в качестве значений.Поскольку MySql использует тот же объем дискового пространства для хранения INT, равного 0 и 2 147 483 647, было бы лучше вместо этого хранить эти 8 столбцов в виде байтового большого двоичного объекта, используя схему хранения типа https://www.sqlite.org/fileformat2.html#varint?

1 Ответ

0 голосов
/ 25 октября 2018

Нет ограничения по количеству строк в одной таблице.По мере того как таблица становится больше, возникает все больше и больше проблем.Столовая таблица отлично работает без нормализации и индексов;таблица миллиардов строк нуждается в обоих плюс сжатые типы данных.И т. Д. И т. Д. (В одном опросе 50M строк было около 96-го процентиля. Я видел более миллиарда строк в одной таблице.)

UUID высасывают производительность для огромных таблиц;старайтесь избегать их.(Да, упаковывать их в BINARY(16) лучше, чем VARCHAR(36).

2/3 из моих таблиц, не использовать AUTO_INCREMENT; вместо этого они имеют «естественный» PKИтак, ясно, я говорю «это зависит», когда речь идет о PK. UserID, вероятно, лучше всего сделать с SMALLINT UNSIGNED или MEDIUMINT UNSIGNED, в зависимости от того, ожидаете ли вы не более 64K или 16M пользователей. Редко это нужноINT, намного меньше BIGINT. (Их размеры составляют 2,3,4,8 байта соответственно.)

Недостаток не AUTO_INCREMENT PK заключается в том, что копия PK сцепляетсяк каждому вторичному ключу, тем самым добавляя к их массе. Однако, грубо говоря:

  • Большой PK, но без вторичных ключей: Fine
  • Большой PK и one вторичный ключ: занимает примерно одинаковое дисковое пространство с ИИ или без него.
  • Большой ПК и несколько вторичных клавиш: ИИ начинает светиться (в пространстве).

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

"Нормализация" столбцов большого размера с повторяющимися значениями - это обычно хорошая идея.(Экономит место, но JOIN, чтобы собрать все вместе, неплохо.)

50M строк с этими 8 столбцами могут составить до 4 ГБ.Это не очень большое.Он не гарантирует игру в BLOB (если код приложения действительно не предпочтет его таким образом.) Тем временем рассмотрим целочисленные типы меньшего размера, чем 4-байтовый INT;рассмотрим UNSIGNED;рассмотрим FLOAT против `DOUBLE.

В MySQL нет эквивалента 'varint'.

Комментарии к http://www.agiledata.org/essays/keys.html:

  • A«ключ» не обязательно однозначно идентифицирует строку.То же самое для «вторичного ключа».Требуется ключевое слово UNIQUE.
  • В MySQL PRIMARY KEY отличается тем, что уникально идентифицирует строку и «кластеризован» с данными.
  • В MySQL этопочти всегда предпочтительнее использовать VARCHAR вместо CHAR.
  • В MySQL AUTO_INCREMENT обычно является предпочтительным методом для суррогатных ключей.
...