2014-12-16 5 views
1

У меня возникла проблема с проектированием структуры таблицы, и я хотел бы услышать ваш ввод. Я создаю таблицу, которая должна содержать около 1-2-миллиметровых строк, позволяет называть их пользователями, и для каждого пользователя мне нужно хранить около 500 логических значений. Основное внимание в этой таблице должно быть быстрым, чтобы читать, нет никакого акцента на размер или время записи. Основные запросы будут касаться выбора количества пользователей, соответствующих различным значениям булевых столбцов, как true или false.Использование масок в таблице MySQL

Итак, вот мой вопрос: я должен проектировать в своем уме.

  • Сначала идет прямо на один вид, я буду только 1 таблица с 500 столбцами, которые являются логическим/TINYINT и просто найти результаты с простыми запросами фильтрации с одной таблицей. Не уверен в скорости этого запроса, и о возможностях MySQL работать с таким количеством столбцов.

  • Второй вариант несколько сложный. Я хотя бы об хранении логических значений в качестве флагов в маске, поэтому количество столбцов было бы значительно уменьшено, но не уверен, хотя о скорости при использовании побитовых операций в SELECT в WHERE.

У кого-нибудь есть опыт работы с такими данными и сравнение скорости между аналогичными методами? Или кому-нибудь лучше понять, как подойти к этому?

+0

базы данных nonSQL, в которых хранятся значения как JSON или что-то. –

+0

. Моим основным для вас является то, что я использую поразрядное использование в качестве системы разрешений. Таким образом, каждый из моих пользователей имеет 1 столбец для значения разрешения, который может идти от 2 до 2^32, и довольно хорошо работать таким образом. –

+0

Вот главный вопрос: как вы будете запрашивать эту таблицу? Только по идентификатору пользователя? По шаблонам логических значений (например, 'WHERE a = 1 AND b = 0 AND d = 1'? Вот еще один ключевой вопрос: можете ли вы добавить еще одно логическое значение? –

ответ

1

Вы должны проверить два разных подхода к данным образца в вашей системе. «Обычный» способ хранения данных в SQL будет выделять 1 байт за каждое логическое значение. Таким образом, данная запись будет составлять около 500 байтов (возможно, плюс некоторые дополнительные накладные расходы). Побирая бит, вы можете поместить это в 63 байта или около того с дополнительным усложнением более сложного доступа. MySQL может легко обрабатывать 500 столбцов.

При нормальных обстоятельствах разница не будет такой большой. Уменьшение размера записей в 8 раз уменьшает количество требуемых страниц и может быть разницей между установкой данных в памяти или отсутствием установки в памяти - и это может быть значительным повышением производительности. (На самом деле, несколько миллионов записей по 500 байт каждый должны легко вписаться в доступный кэш, так что это, возможно, не будет большой разницей).

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

В целом, для нескольких флагов прирост производительности за счет поддержки битов, вероятно, не стоит дополнительной сложности при доступе. Однако у вас есть довольно экстремальный случай, когда бит-упаковка может быть оправдана.

-1

Вы можете создать структуру SQL, которая будет эмулировать эти 500 значений bollean как , например 8 * (64 бит) столбца BIGINT.

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

Если вы хотите спросить свою БД для булевского набора, вы должны перенести его на целое число сначала.

Так что в каждом запросе вы спросите 8 наборов bigints, а не 500 булевых.

Это может помочь. Каждая колонка должна иметь индекс, конечно.

Пример: значение 2 для целых чисел без знака (4 бита) будет представлено как 0010 Он может содержать 4 булевых столбца, которые имеют значения, false, false, true, false.

+0

Будет очень сложно найти отдельные биты внутри целого числа с помощью этот метод. Вам нужно будет выполнить вычисления битов перед запросом базы данных. – ericpap

+0

Вам нужно будет выполнить вычисления битов перед базой запросов. Это не проблема. Для каждого набора условий вам нужно вычислить только 8 больших значений. Это может ускорить выполнение –

+0

Итак, предположим, мне нужно найти пользователей с битами 2, 8, 17, 65, 122 и 222, установленными в true. Как вы это сделаете? – ericpap

2

Рассмотрите третий вариант. Это немного сложнее, но может улучшить производительность. Вы будете нуждаться в 3 таблицы:

  • Пользователи
  • Права доступа
  • PermissionsxUser

Таблица пользователей только информацию о пользователях. Ваши «столбцы» переводятся в строках таблицы разрешений. Затем для каждого разрешения, которое вы хотите добавить, добавьте строку в таблицу PermissionsxUser. Конечно, каждой таблице нужен идентификатор.

Это также более эффективно, потому что вы добавляете записи только при предоставлении конкретного разрешения. Если у Пользователей нет записи для конкретного идентификатора разрешения, это не позволяет делать это действие.

+0

Я, хотя об этом, кажется, самый «чистый» метод. Меня беспокоит скорость здесь, было бы действительно быстрее работать с тремя объединенными таблицами, а не с одним? – KillerFrca

+0

Вы можете легко индексировать эти 3 таблицы, потому что не существует булевых полей. Таблица пользователей - это индекс по идентификатору пользователя, PermissionTable по PermissionID и PermissionsxUser по обоим полям. Таким образом, запрос может быть очень быстрым. Вы также можете использовать предложение IN для поиска определенного набора разрешений. Я делаю это в своих системных разрешениях и работает отлично. – ericpap

+0

Вы также можете использовать идентификатор char, чтобы указать разрешение, что очень легко. В моей системе создайте идентификаторы типа This: «System.Articules.ADD» или «Sysmtem.Clients.Delete», чтобы определить, что пользователь может или не может сделать. – ericpap

Смежные вопросы