powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Проектирование БД [игнор отключен] [закрыт для гостей] / Хранение и поиск текстовых строк
22 сообщений из 22, страница 1 из 1
Хранение и поиск текстовых строк
    #33822952
flyinghero
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Интересно, как правильнее реализовать работу с "интересами", как это сделано, например, на LiveJournal.com

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

Как правильнее хранить такую информацию и искать по ней пользователей.
Я вижу два варианта:

1. Хранить в большой таблице пары значений int user_id, char interest

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

2. Хранить в большой таблице пары int user_id, int interest_id, при этом все строки с "интересами" будут храниться в отдельной таблице int interest_id, char interest_name.

Вопрос в том, что экономнее по времени и по памяти.
...
Рейтинг: 0 / 0
Хранение и поиск текстовых строк
    #33823112
mir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
По варианту 2: тут особо не наэкономишь, а мороки лишней будет много. Полагаю, речь не идет о таких уж объемах, чтобы надо было экономить.
Другой вопрос, если этот поиск по интересом очень важен. Тут можно поморочится, вроде приведения ключевых слов к единой морфологии или выбора их из списка, устранения опечаток и т.д. Тут 2 вариант может и получше будет. Но судя по задаче, возможность поиска по интересам --- побочная фича, так что это все лишнее.
...
Рейтинг: 0 / 0
Хранение и поиск текстовых строк
    #33823273
DocAl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Хм. И какого рода морока будет во втором варианте?
...
Рейтинг: 0 / 0
Хранение и поиск текстовых строк
    #33823567
flyinghero
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Поиск по интересам будет, скорее всего, использоваться не так часто, однако вот количество интересов будет весьма значительно. Например, если пользователей станет много (десятки, а то и сотни тысяч), на каждого будет приходиться примерно по 15 ключевых слов, то есть вполне возможно, что число записей перевалит за миллион.
...
Рейтинг: 0 / 0
Хранение и поиск текстовых строк
    #33823586
flyinghero
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Второй вариант мне больше нравится тем, что

a) поиск по int идет быстрее, чем по строкам
b) экономится память, за счет удаления многократных повторений строк.

С этим вариантом возиться действительно нужно гораздо больше, чем с первым (добавление интересов, из редактирование и тд). Вот и хотелось бы знать, стоит ли игра свеч.
...
Рейтинг: 0 / 0
Хранение и поиск текстовых строк
    #33823619
DocAl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я не понимаю, что со вторым вариантом возиться-то?
INSERT IGNORE и JOIN при заполнении, JOIN при извлечении информации. Причём JOIN простейший, по первичному ключу!
Для денормализации базы должны быть какие-то основания, тут их просто нету, так зачем же сразу портачить?
...
Рейтинг: 0 / 0
Хранение и поиск текстовых строк
    #33823789
mir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DocAlЯ не понимаю, что со вторым вариантом возиться-то?
INSERT IGNORE и JOIN при заполнении, JOIN при извлечении информации. Причём JOIN простейший, по первичному ключу!
Для денормализации базы должны быть какие-то основания, тут их просто нету, так зачем же сразу портачить?Да можно и 2 вариант, конечно, спору нет. На один джойн больше, плюс посложнее парсинг ввода. Кстати, что такое INSERT IGNORE?
И еще, где ж тут денормализация была?
...
Рейтинг: 0 / 0
Хранение и поиск текстовых строк
    #33823806
Фотография iscrafm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
flyingheroВторой вариант мне больше нравится тем, что

a) поиск по int идет быстрее, чем по строкам

Конечно. И условия удобно задавать: Найди ка мне людей с 10, 48 и 23 -м интересом
...
Рейтинг: 0 / 0
Хранение и поиск текстовых строк
    #33824018
Слабости РБД в целом и "ключей" в частности проявляются в любой задаче.
В классической ОБД:

Человек <-- Имеет/Присутствует у --> Интерес

Хотя можно использовать и характеристику "Интерес" с типом "набор строк" в объекте Человек. Странно, что такой специалист, как mir, не видит, в этом случае, денормализации. Видимо это связано со слабой "технологией" нормализации в РБД.
...
Рейтинг: 0 / 0
Хранение и поиск текстовых строк
    #33824022
DocAl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mir DocAlЯ не понимаю, что со вторым вариантом возиться-то?
INSERT IGNORE и JOIN при заполнении, JOIN при извлечении информации. Причём JOIN простейший, по первичному ключу!
Для денормализации базы должны быть какие-то основания, тут их просто нету, так зачем же сразу портачить?Да можно и 2 вариант, конечно, спору нет. На один джойн больше, плюс посложнее парсинг ввода. Кстати, что такое INSERT IGNORE?
И еще, где ж тут денормализация была?
Так в чём состоит более сложный парсинг ввода? Подозреваю, что эта "более сложность" и заменяет у вас INSERT IGNORE ,)
...
Рейтинг: 0 / 0
Хранение и поиск текстовых строк
    #33824031
К тому же, "интерес" может быть любительский или подкрепленный образованием и т.д. Так что денормализация не выглядит здесь обоснованной, совершенно.
...
Рейтинг: 0 / 0
Хранение и поиск текстовых строк
    #33824048
DocAl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
iscrafm flyingheroВторой вариант мне больше нравится тем, что

a) поиск по int идет быстрее, чем по строкам

Конечно. И условия удобно задавать: Найди ка мне людей с 10, 48 и 23 -м интересом
Если это сарказм, то он тут неуместен. Джойн по первичному ключу -- штука быстрая, а выборка по строчным значениям из тысячи уникальных записей будет куда быстрее выборки по миллиону неуникальных.
Я вообще, не особо понимаю, о чём идёт спор. Второй предлагаемый вариант является классической нормализованной структурой, в которой под сущность "интерес" выделена отдельная таблица. Первый же -- некая полумера между "зафутболить все интересы в строку через запятую" и нормальной реализацией. Если вы видите преимущества такого решения -- так покажите их, только, пожалуйста, с примерами.
...
Рейтинг: 0 / 0
Хранение и поиск текстовых строк
    #33824646
flyinghero
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
iscrafm flyingheroВторой вариант мне больше нравится тем, что

a) поиск по int идет быстрее, чем по строкам

Конечно. И условия удобно задавать: Найди ка мне людей с 10, 48 и 23 -м интересом

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

вы меня почти убедили в целесообразности второго варианта :) правда, честно говоря, про INSERT IGNORE не слышал никогда.
...
Рейтинг: 0 / 0
Хранение и поиск текстовых строк
    #33825498
flyinghero
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
По-моему возни со вторым вариантом все равно не избежать. Например пользователь задал себе несколько ключевых слов. Из них надо в таблицу с интересами вставить только новые, вместе с тем получить id этих новых + получить id остальных неновых интересов. Затем нужно из таблицы пользователь-интерес удалить все записи конкретного пользователя и записать на их место только что полученные id интересов. INSERT IGNORE здесь вообще никак не помогает.
...
Рейтинг: 0 / 0
Хранение и поиск текстовых строк
    #33825558
DocAl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Нда?
Ну вот вам пример. Синтаксис MySQL, потому что-то может различаться для других диалектов, конечно.
Описание основных таблиц:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
CREATE TABLE interests (
	id INT UNSIGNED NOT NULL auto_increment,
	name VARCHAR( 50 ) NOT NULL,
	PRIMARY KEY (id),
	UNIQUE KEY (name)
) ENGINE=InnoDB;
CREATE TABLE users (
	id INT UNSIGNED NOT NULL auto_increment,
	name VARCHAR( 50 ) NOT NULL,
	-- password, etc.
	PRIMARY KEY (id),
	UNIQUE KEY (name)
) ENGINE=InnoDB;
CREATE TABLE users_interests (
	user_id INT UNSIGNED NOT NULL,
	interest_id INT UNSIGNED NOT NULL,
	PRIMARY KEY (user_id, interest_id),
	CONSTRAINT FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE CASCADE,
	CONSTRAINT FOREIGN KEY (interest_id) REFERENCES interests (id) ON DELETE CASCADE
) ENGINE=InnoDB;
При внесении данных будет ещё использована временная таблица:
Код: plaintext
1.
2.
3.
4.
CREATE TEMPORARY TABLE tui (
	interest_name VARCHAR( 50 ) NOT NULL,
	UNIQUE KEY(interest_name)
);
Итак,
Код: plaintext
1.
START TRANSACTION
делаем раз, заносим пользователя в таблицу users:
Код: plaintext
1.
INSERT INTO users (name, ...) VALUES ('Vasja', ...)
делаем два, создаём временную таблицу и заносим в неё список указанных интересов:
Код: plaintext
1.
INSERT IGNORE INTO tui VALUES (...), ...
делаем три, добавляем новые интересы в таблицу interests:
Код: plaintext
1.
INSERT IGNORE INTO interests (name) SELECT interest_name AS name FROM tui
делаем четыре, вносим в таблицу users_interests интересы данного пользователя:
Код: plaintext
1.
INSERT IGNORE INTO users_interests SELECT users.id AS user_id, interests.id AS interest_id FROM interests JOIN tui ON interests.name=tui.interest_name JOIN users ON users.name='Vasja'
удаляем временную таблицу, подтверждаем транзакцию:
Код: plaintext
1.
2.
DROP TABLE tui;
COMMIT;
Так ли много возни, чтобы на ней экономить?
...
Рейтинг: 0 / 0
Хранение и поиск текстовых строк
    #33825659
flyinghero
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Спасибо, не додумался :)
...
Рейтинг: 0 / 0
Хранение и поиск текстовых строк
    #33826484
mir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DocAl mir DocAlЯ не понимаю, что со вторым вариантом возиться-то?
INSERT IGNORE и JOIN при заполнении, JOIN при извлечении информации. Причём JOIN простейший, по первичному ключу!
Для денормализации базы должны быть какие-то основания, тут их просто нету, так зачем же сразу портачить?Да можно и 2 вариант, конечно, спору нет. На один джойн больше, плюс посложнее парсинг ввода. Кстати, что такое INSERT IGNORE?
И еще, где ж тут денормализация была?
Так в чём состоит более сложный парсинг ввода? Подозреваю, что эта "более сложность" и заменяет у вас INSERT IGNORE ,)И все же, что такое INSERT IGNORE? По-моему, в стандарте такого нет. Если это нестандартная фича MySQL, то почему вы ее столь активно предлагаете, ведь в исходной постановке ни слова не говорилось об используемой СУБД. Если автор вопроса заведомо использует MySQL, то спора нет. Если же не заведомо, то попробуйте реализовать ваш подход без INSERT IGNORE. Вот тут-то, полагаю, и вылезут дополнительные сложности, о которых я и говорил.

Кстати, на вопрос про денормализацию вы так и не ответили. Какая НФ нарушена и почему?
...
Рейтинг: 0 / 0
Хранение и поиск текстовых строк
    #33827327
DocAl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
При указании ключевого слова IGNORE, оператор INSERT обрабатывает ошибки, возникшие при внесении данных как предупреждения. Эффективно, в таком применении, как приводилось в примере, это означает, что все вносимые записи, не удовлетворяющие ограничениям уникальности (или любым другим CONSTRAINT, в общем случае) игнорируются. Т.к. у каждой СУБД свой диалект, в чём-то расширяющий стандарт, а в чём-то ему и не соответствующий, я не вижу причины, почему бы мне не приводить пример на основе одного из наиболее часто используемых в вебе.
...
Рейтинг: 0 / 0
Хранение и поиск текстовых строк
    #33827852
mir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DocAlПри указании ключевого слова IGNORE, оператор INSERT обрабатывает ошибки, возникшие при внесении данных как предупреждения. Эффективно, в таком применении, как приводилось в примере, это означает, что все вносимые записи, не удовлетворяющие ограничениям уникальности (или любым другим CONSTRAINT, в общем случае) игнорируются. Т.к. у каждой СУБД свой диалект, в чём-то расширяющий стандарт, а в чём-то ему и не соответствующий, я не вижу причины, почему бы мне не приводить пример на основе одного из наиболее часто используемых в вебе.Про смысл INSERT IGNORE я так примерно и думал. В принципе, полезная штука. Правда вы должны признать, что все таки очень специфичная, поэтому налегать на нее с самого начала обсуждения, как делали вы, было, хм... не вполне корректно, так как автор темы про СУБД ничего не оговорил. Ладно, пора заканчивать.

P.S. Про денормализацию в 1 варианте, будем считать, вы сгоряча брякнули, не подумав.
...
Рейтинг: 0 / 0
Хранение и поиск текстовых строк
    #33827953
DocAl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Хм, да собственно, 2НФ нарушается, вроде бы очевидно?
...
Рейтинг: 0 / 0
Хранение и поиск текстовых строк
    #33828001
DocAl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DocAlХм, да собственно, 2НФ нарушается, вроде бы очевидно?
Да, а вот это я действительно погорячился.)
...
Рейтинг: 0 / 0
Хранение и поиск текстовых строк
    #33837932
ModelR
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DocAl DocAlХм, да собственно, 2НФ нарушается, вроде бы очевидно?
Да, а вот это я действительно погорячился.)Можно назвать преобразование варианта 1 в 2 "суррогатизацией".
...
Рейтинг: 0 / 0
22 сообщений из 22, страница 1 из 1
Форумы / Проектирование БД [игнор отключен] [закрыт для гостей] / Хранение и поиск текстовых строк
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]