2010-09-21 4 views
3

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

  • столика items
  • стол lists, к которым эти элементы могут быть связаны
  • таблица users

Условие: список может принадлежать все или один конкретный пользователь

Что я хотел бы сделать, так это создать «глобальные» списки, которые существуют навсегда. Но должна быть возможность «перезаписать» этот глобальный список пользовательской. Пример для случайного пользователя:

  • глобальный список называется книги
  • конкретного пользователя список CDs

Теперь при получении списков для этого пользователя я должен получить как глобальные списков книг и списка конкретных пользователей. Но что, если у этого пользователя есть определенный список книг?

  • глобальный список называется книги
  • конкретного пользователя список книги
  • конкретного пользователя список CDs

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

Возможные решения
Легче всего было бы что-то вроде этого:

table: lists 
- id 
- name 
- userId

Если идента IS NULL это означало бы, что это глобальный список, но когда это NOT NULL принадлежит конкретному пользователю. Таким образом, первый пример будет для USERID = 1:

id name userId 
1 books NULL 
2 cds  1

Чтобы получить списки для этого пользователя:

SELECT * FROM lists WHERE userId = 1 OR userId IS NULL

Но я застрял в следующей части:

id name userId 
1 books NULL 
2 cds  1 
3 books 1

Здесь первый список «книг» является глобальным, но у этого пользователя также есть список «книг» для конкретного пользователя. В этом случае можно игнорировать глобальный список и возвращать только пользовательский?

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

Вопрос:
Какой самый лучший и самый эффективный способ установить это в базе данных, так что я могу легко получить правильные списки для конкретного пользователя?

ответ

0

Для вашего текущего проекта вы можете получить список пользователя следующим образом:

SELECT * FROM lists 
WHERE userId = 1 
UNION ALL 
Select * from lists g 
Where userId IS NULL 
AND NOT EXISTS (SELECT 1 from lists l where g.name = l.name and userid = 1) 

т.е. выберите определенный пользователь списки и глобальное не-переопределено пользователем

0

Что делать, если вы должны были фильтровать элементы вместо списков?

Select distinct -- items from user-specific lists 
     ItemName 
    , ItemType 
from User  as u 
join UserList as x on x.UserId = u.UserId 
join List  as t on t.ListId = x.ListId 
join ListItem as y on y.ListId = t.ListId 
join Item  as m on m.ItemId = t.ItemId 
where ListType = 'custom' 
and u.UserId = some_user_id 
UNION 
Select distinct 
     ItemName -- items from global lists 
    , ItemType 
from List  as t on t.ListId = x.ListId 
join ListItem as y on y.ListId = t.ListId 
join Item  as m on m.ItemId = t.ItemId 
where ListType = 'global' 

order by ItemType, ItemName 
; 

alt text

0

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

я предлагаю это (извините за грязный диаграммы UML)

List diagram

идея в том, что вас ка ld использовать «наследие» для разделения двух типов списков: UserDefinedList и DefaultLists. Как вы можете видеть, только пользователи UserDefinedLists связаны с пользователями, а списки по умолчанию открыты для любого пользователя, который хочет их использовать. Конечно, когда кто-то хочет создать список книг, вы могли бы сообщить пользователю, что список был создан, но на самом деле вы ничего не вставляете в базу данных.

Если вы хотите отображать списки пользователей, вы показываете UserDefinedLists и все списки по умолчанию.

Возможно, это может показаться странным, но мораль этой истории заключается в том, что Heritage полезен в Базах данных, когда у вас есть разные типы элементов (например, списки), и каждый тип имеет разные отношения с другими таблицами (например, UserDefinedLists относятся к пользователям и DefaultLists не являются, но они оба типа List)

Надеюсь, что это поможет

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