2016-07-21 4 views
0

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

пользователей хранятся в: (users :: id -> [id, email])

create table users (
    id integer primary key autoincrement not null unique, 
    email varchar[255] not null  
); 

и они имеют профиль таблицу:

create table profiles (
    id integer unique primary key not null,  
    foreign key(id) references users(id) 
); 

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

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

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

  1. получить идентификатор коллекции из таблицы профилей.
  2. доступа таблица с именем результат запроса 1.

Что чувствует себя неправильно, а также.

Есть ли другой подход для отображения первичного ключа в коллекцию вещей, чем создание таблицы? А если нет, следует ли использовать разные базы данных, такие как «friend_lists.db» для хранения всех этих таблиц?

Спасибо заранее.

ответ

1

Вы считаете, что динамическое создание таблиц «странно». Я видел, как многие люди в Stack Overflow пытаются использовать этот анти-шаблон.

Что бы вы ни планировали параметризовать имена своих таблиц, перейдите к столбцу в одной таблице.

Например, если вы думаете об использовании этой схемы:

CREATE TABLE user_1234_music(track_name TEXT); 
CREATE TABLE user_5678_music(track_name TEXT); 
CREATE TABLE user_5483_music(track_name TEXT); 
-- and so on 

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

CREATE TABLE friends(user_id INTEGER REFERENCES users(id), track_name TEXT); 

Это имеет несколько преимуществ:

  • Нет популярный движок базы данных SQL не поддерживает использование параметров запроса в именах таблиц, то есть вы должны использовать манипуляции со строками, чтобы «пропустить» в значении имени таблицы , подвергая вас уязвимостям SQL-инъекций.
  • Большинство баз данных не имеют возможности динамически выбирать между разными именами таблиц на основе результатов запроса. Столбцы легко фильтруются, либо в пунктах WHERE, либо JOIN.
  • Изменения схемы (добавление/удаление столбцов, индексов, ограничений и т. Д.) Должны выполняться только на одной таблице.
  • Базы данных построены для масштабирования до миллионов строк. Они не так хорошо оснащены для масштабирования с большим количеством таблиц (или столбцов, если на то пошло).
+0

Позвольте мне убедиться, правильно ли я вас понимаю. Предлагаете ли вы сохранить список друзей в одной таблице и отфильтровать его друзьями, которых вы ищете? например, друзья Боба и друзья Эми находятся в одной таблице, но когда вы ищете друзей Боба, вы ищете строки по идентификатору Боба. – Dmitry

+0

Чувствуется, что перемещение этих данных в идентификатор сопоставления json-файла ко всем идентификаторам друзей будет более эффективным с точки зрения вычислений, поскольку я не уверен, что база данных каким-то образом пропускает «цикл над миллионами строк, чтобы найти 100 друзей этого парня», и оптимизирует его для что-то более разумное, тогда как отношения просто числа -> много чисел, он считает, что неправильно просто положить всех друзей в один стол. – Dmitry

+0

@Dmitry Именно это. 'SELECT friend_id FROM friends WHERE user_id = bobs_id'. Вы также можете использовать соединения: 'SELECT users.name FROM friends INNER JOIN users ON users.id = friends.friend_id WHERE friends.user_id = bobs_id' (не может быть, если вы используете JSON). Если у вас есть индекс, настроенный для столбцов, которые вы часто запрашиваете, поиск будет быстрым. –

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