Как без проблем хранятся теги элемента в базе данных?
У каждого элемента есть несколько тегов. Я прочитал несколько ответов о том, как это сделать:
Но я думаю, что есть лучшее решение. Почему мы не можем просто включать теги в виде длинной строки для каждого элемента?
Table : Brand_Shops
Columns : brand_id, brand_name, content, tags
Пример :
1 || Nike || shoes bags sports football soccer t-shirts track-pants
2 || GAP || wallets t-shirts jeans shoes perfumes
У него нет атомарность, но он полностью соответствует цели тегирования. Если необходимо добавить новый бренд, вместе с ним можно просто добавить новые теги. Из-за этого его тоже будет очень легко получить. Я не понимаю, почему это не эффективное решение.
Эффективен для сопровождения кода и прост в использовании
Что ж, IMHO, хорошее обслуживание кода = простой код = не используйте сложный код для разделения и добавления строк в одну строку. Просто сделай простую вставку


I don't understand why this is not an efficient solution.
Это неэффективно, потому что вам нужно извлекать и разбивать / искать эту строку для каждого запроса.
Когда вы делаете что-то вроде (как указано в ваших ссылках) Three tables (one for storing all items, one for all tags, and one for the relation between the two), вы можете использовать реальную мощь реляционной базы данных, индекс.
Вместо того, чтобы разбивать каждую строку на тег или набор тегов ... это уже сделано; вы просто получаете то, что хотите. Итак, если вы ищете «обувь», он идет прямо туда (с использованием индекса, вероятно, log n или быстрее) и возвращает как Nike, так и GAP. Он будет делать это независимо от того, сколько у вас тегов, независимо от того, сколько у вас компаний.
В системе с 3 таблицами вы делаете всю тяжелую работу заранее, а затем просто выполняете поиск.
Если вы собираетесь запускать это локально или с ограниченным числом пользователей, ваше решение может подойти. Кодировать также проще. Как только ваши запросы начнут занимать больше нескольких секунд, вы, вероятно, захотите обновить свою систему тегов. Если вы сделаете это таким образом, напишите код поиска отдельно на случай, если вам нужно его вырвать.
Вопрос из комментария:
Can you give an example of a 3 table system that is normalized with atomicity
Конечно.
По сути, вы попросили третью нормальную форму, что является моей обычной целью.
(Признаюсь, я часто не делаю 3NF, потому что оптимизирую; например, сохранение почтового индекса с адресами - если вы не ходите в школу, это лучший выбор)
--Sample SQL stackoverflow.com/questions/50793168/database-design-for-tags-or-tagging/50818392
IF NOT EXISTS (SELECT * FROM sys.schemas WHERE name = N'ChrisC')
BEGIN
EXEC sys.sp_executesql N'CREATE SCHEMA [ChrisC] AUTHORIZATION [dbo]'
IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[ChrisC].[Brands]') AND type in (N'U'))
AND NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[ChrisC].[BrandTags]') AND type in (N'U'))
AND NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[ChrisC].[Tags]') AND type in (N'U'))
BEGIN
CREATE TABLE [ChrisC].[Brands]([pkBrand] [int] IDENTITY(101,1) NOT NULL,[Name] [varchar](40) NULL) ON [PRIMARY]
INSERT INTO [ChrisC].[Brands]([Name])VALUES('Nike'),('GAP')
CREATE TABLE [ChrisC].[BrandTags]([pk] [int] IDENTITY(1,1) NOT NULL,[Brand] [int] NULL,[Tag] [int] NULL) ON [PRIMARY]
INSERT INTO [ChrisC].[BrandTags]([Brand],[Tag])VALUES
(101,201),(101,202),(101,203),(101,204),(101,205),(101,206),(101,207),
(102,208),(102,209),(102,203),(102,207),(102,210)
CREATE TABLE [ChrisC].[Tags]([pkTag] [int] IDENTITY(201,1) NOT NULL,[Tag] [varchar](40) NULL) ON [PRIMARY]
INSERT INTO [ChrisC].[Tags]([Tag])VALUES
('bags'),('football'),('shoes'),('soccer'),('sports'),('track-pants'),('t-shirts'),('jeans'),('perfumes'),('wallets')
SELECT b.[Name], t.Tag
FROM chrisc.Brands b
LEFT JOIN chrisc.BrandTags bt ON pkBrand = Brand
LEFT JOIN chrisc.Tags t ON bt.Tag = t.pkTag
WHERE b.[Name] = 'Nike'
-- Stop execution here to see the tables with data
DROP TABLE [ChrisC].[Brands]
DROP TABLE [ChrisC].[BrandTags]
DROP TABLE [ChrisC].[Tags]
END
IF EXISTS (SELECT * FROM sys.schemas WHERE name = N'ChrisC') DROP SCHEMA [ChrisC]
END
Можете ли вы показать на одном примере, как теги будут выглядеть в системе из трех таблиц в примере Nike. Потому что я чувствую, что правило атомарности будет нарушено, несмотря ни на что. И база данных не будет нормализована.
Сделанный. Дайте мне знать, если у вас есть вопросы (я использовал настраиваемую схему, которая, надеюсь, не сбивает с толку)
Определите эффективный. Удобно для письма? эффективен для чтения? эффективен для обслуживания кода?