Реклама на сайте Advertise with us
Тема: Оптимизация SQL базы Расширенный поиск по форуму
 
Внимание! В связи с устареванием топика эта страница была взята из кэша.
Автор Сообщение
Информация о пользователе SeRu


Зарегистрирован: 23.07.02
Сообщения: 329
Ссылка на сообщениеДобавлено: 25/04/04 в 01:33     

Вот есть у меня база и в ней 8-15 полей, которые могут принимать значения только да или нет, 1 или 0 (истинно или ложно). Например:
есть товар в продаже - "1", нету "0". И вот таких полей в SQL базе у меня 8-15штук. Я думаю стоит ли создавать столько полей или можно сделать всё через одно поле? Возможно в этом единственном поле хранить запись типа abcde... cd - есть, а если нету, то abe... Как поступить?

K началу

 
Информация о пользователе Ru


Зарегистрирован: 17.04.04
Сообщения: 14
Ссылка на сообщениеДобавлено: 25/04/04 в 01:59     

Это зависит от того как у тебя выборка из этой базы идет. Если надо смотреть отдельные товары, то нужно делать разные поля, если все подряд, то лучше в одно поле. И вообще как часто идет постинг. Может каких-то товаров больше, каких-то меньше. Тогда имхо лучше вообще сделать одну таблицу с 2-мя полями (тип товара и наличие его). Ну и можно еще одну таблицу с описанием товара, чтобы самому не запутаться. Хотя наверное последний вариант лучший во всех отношениях icon_smile.gif

K началу

 
Информация о пользователе mr.GOD


Зарегистрирован: 19.11.03
Сообщения: 674
Ссылка на сообщениеДобавлено: 25/04/04 в 03:36     

делаешь таблицу:

ид товара(id) | описание товара (desc)| наличие(status)




id - uniq , not null , auto increment
desc - text
status -char 3 , YES или NO

вот собсно всегда сможешь узнать что и как icon_smile.gif если я все правильно понял icon_smile.gif

K началу

 
Информация о пользователе bleed


Зарегистрирован: 19.02.03
Сообщения: 282
Ссылка на сообщениеДобавлено: 25/04/04 в 05:26     

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

K началу

 
Информация о пользователе Dragon


Зарегистрирован: 09.02.03
Сообщения: 270
Ссылка на сообщениеДобавлено: 25/04/04 в 08:10     

mr.GOD писал:

desc - text
status -char 3 , YES или NO


1. Text и Varchar в нагруженной таблице использовать крайне не рекомендуется.

2. "Да" или "Нет" не проще ли хранить как Char(1) в виде единицы или нуля? icon_smile.gif

K началу

 
Информация о пользователе SeRu


Зарегистрирован: 23.07.02
Сообщения: 329
Ссылка на сообщениеДобавлено: 25/04/04 в 08:22     

Вот примерно у меня такая ситуация.
На странице выводиться список телевизоров 10-200штук, и нужно вывести для каждого телевизора характеристики (эти 8-15 полей):
1) Плоский экран (Да/Нет)
2) Пульт управления (Да/Нет)
3) Телетекст (Да/Нет)
4) Встроенные игры (Да/Нет)
...
15) Пульт управления (Да/Нет)

То есть например.
>Philips - [1
....
15]

>Sony - [1
....
15]

>Rolsen - [1
....
15]

K началу

 
Информация о пользователе Kernel Team


Зарегистрирован: 02.11.03
Сообщения: 147
Ссылка на сообщениеДобавлено: 25/04/04 в 08:51     

SeRu писал:
Возможно в этом единственном поле хранить запись типа abcde... cd - есть, а если нету, то abe... Как поступить?


Можно создать таблицу с номером товара и описанием товара (в твоем случае характеристики). (номера с 0 до n), а в текстовом поле хранить что-то вроде 1010001001, где порядковый номер будет показателем товара (из первой таблицы), а 1 или 0 - показатель его наличия...
К твоему примеру вроде более или менее подходит...

Удачи!

K началу

 
Информация о пользователе SeRu


Зарегистрирован: 23.07.02
Сообщения: 329
Ссылка на сообщениеДобавлено: 25/04/04 в 08:54     

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

K началу

 
Информация о пользователе Butch


Зарегистрирован: 14.09.03
Сообщения: 92
Ссылка на сообщениеДобавлено: 25/04/04 в 09:41     

Ну если все флаги в твоем случае возможно хранить в одном поле, то я бы предложил хранить их в в целых числах. Работа с числовыми данными всегда быстрее нежели с текстовыми.
Смотришь сколько тебе нужно флагов и выбираешь формат целого числа от TINYINT (до 8 флагов) до INT (до 32 флагов). "Назначаешь" соответствие биты-флаги и отсюда пляшешь. Например, 1 бит - наличие на складе, 2 бит - отображать в прайсе, ну и т.д.
Соответственно, перед обращением к мускулю формируешь небходимое для запроса число с помощью бинарных операций.
НО, такое работает только при строгих запросах. Т.е. если тебе, например, при выборке не важно значение 5,8 и 11-го битов, то тут придутся поплясать, хотя всегда можно найти весьма элегантное решение любой задачи. Главное - это четко знать как все должно работать в итоге ;)))

K началу

 
Информация о пользователе bleed


Зарегистрирован: 19.02.03
Сообщения: 282
Ссылка на сообщениеДобавлено: 25/04/04 в 10:08     

cjmaster писал:
Можно создать таблицу с номером товара и описанием товара (в твоем случае характеристики). (номера с 0 до n), а в текстовом поле хранить что-то вроде 1010001001, где порядковый номер будет показателем товара (из первой таблицы), а 1 или 0 - показатель его наличия...
К твоему примеру вроде более или менее подходит...
Удачи!

как я понял вы хотите всю информацию о продукте хранить в одном поле... мда.
Короче, а если ему необходимо будет сделать выборку тех телевизоров у которых плоский экран(например), и что тогда не обойдешся просто SQL запросом к базе, а надо будет обрабатывать каждое полее еще и по символьно... вы сами подумайте какую нагрузку создаст это!!!
Я бы сделал так:
id unique, not null, auto_increment - primary key
name char(15), index - модель
desc char(100) - описание
rc char(1), index- пульт управления 0 или 1
scr char(1), index- плоский экран
game char(1), index- игры
...
и т.д.
не забудь про индексы

K началу

 
Информация о пользователе Butch


Зарегистрирован: 14.09.03
Сообщения: 92
Ссылка на сообщениеДобавлено: 25/04/04 в 10:42     

Короче, делаешь числовое поле, где каждый бит отвечает за то или иное свойство. По твоему примеру:
0-ой бит - Плоский экран (Да/Нет)
1-ый - Пульт управления (Да/Нет)
2-ой - Телетекст (Да/Нет)
3-ий - Встроенные игры (Да/Нет)
...
14-й - Virtual Dolby Surround
таким образом мы вписываемся в 16 бит, т.е. 2 байта - используем SMALLINT UNSIGNED (беззнаковый, чтоб не особо путаться)
Чтобы получить число, которое нужно занести в это поле используем формулу:
SETS = N0*2^0 + N1*2^1 + N2*2^2 + N3*2^3 + ... + N14*2^14, где N0-N14 - 0 или 1 (Нет или Да)
Для осуществления выборки по определенным пораметрам вычисляем битовую комбинацию, соотвествующую этим параметрам по той же формуле, что и SETS. Например, для поиска ТВ с плоским экраном и VDS это будет RSETS = 2^0 + 2^14.
Для строгой выборки (т.е. ТВ имеет только плоский экран и VDS, все остальное отсутствует) используем запрос
SELECT * FROM table WHERE SETS=RSETS;
Для выборки нестрогих соответствий (где обязательно есть плоский экран и VDS + все что угодно другое) используем запрос вида
SELECT *,SETS & RSETS AS FSETS FROM table WHERE FSETS=RSETS;
Насчет структуры AS не уверен, посмотри в доках как полю имя присвоить. Или это можно обойти чем-то вроде
SELECT SETS & RSETS,* FROM table WHERE 0=RSETS;
В общем, это уже детали.
Таким образом ты получишь 2 байта на все характеристики вместо 15. Плюс выборка, я думаю, будет пошустрее.
По крайней мере я бы сделал так как я описал.

K началу

 
Информация о пользователе mr.GOD


Зарегистрирован: 19.11.03
Сообщения: 674
Ссылка на сообщениеДобавлено: 25/04/04 в 12:47     

Dragon писал:
1. Text и Varchar в нагруженной таблице использовать крайне не рекомендуется.
2. "Да" или "Нет" не проще ли хранить как Char(1) в виде единицы или нуля? icon_smile.gif


ну во-первых про нагрузки автор топика нечего не сказал icon_smile.gif,а во вторых можно и в виде int(1) и еще придумать пару десятков других способов icon_smile.gif , я просто предложил общую структуру.


з.ы.
только сейчас понял что он вообще хотел icon_smile.gif

K началу

 
Информация о пользователе undef


Зарегистрирован: 15.09.03
Сообщения: 357
Ссылка на сообщениеДобавлено: 25/04/04 в 13:39     

Можно попробовать использовать битовые маски как в C.

K началу

 
Информация о пользователе sexvendor


Зарегистрирован: 07.10.03
Сообщения: 66
Ссылка на сообщениеДобавлено: 25/04/04 в 14:12     

Butch писал:
Короче, делаешь числовое поле, где каждый бит отвечает за то или иное свойство. По твоему примеру:
0-ой бит - Плоский экран (Да/Нет)
1-ый - Пульт управления (Да/Нет)
2-ой - Телетекст (Да/Нет)
3-ий - Встроенные игры (Да/Нет)
...
14-й - Virtual Dolby Surround
таким образом мы вписываемся в 16 бит, т.е. 2 байта - используем SMALLINT UNSIGNED (беззнаковый, чтоб не особо путаться)
Чтобы получить число, которое нужно занести в это поле используем формулу:
SETS = N0*2^0 + N1*2^1 + N2*2^2 + N3*2^3 + ... + N14*2^14, где N0-N14 - 0 или 1 (Нет или Да)
Для осуществления выборки по определенным пораметрам вычисляем битовую комбинацию, соотвествующую этим параметрам по той же формуле, что и SETS. Например, для поиска ТВ с плоским экраном и VDS это будет RSETS = 2^0 + 2^14.
Для строгой выборки (т.е. ТВ имеет только плоский экран и VDS, все остальное отсутствует) используем запрос
SELECT * FROM table WHERE SETS=RSETS;
Для выборки нестрогих соответствий (где обязательно есть плоский экран и VDS + все что угодно другое) используем запрос вида
SELECT *,SETS & RSETS AS FSETS FROM table WHERE FSETS=RSETS;
Насчет структуры AS не уверен, посмотри в доках как полю имя присвоить. Или это можно обойти чем-то вроде
SELECT SETS & RSETS,* FROM table WHERE 0=RSETS;
В общем, это уже детали.
Таким образом ты получишь 2 байта на все характеристики вместо 15. Плюс выборка, я думаю, будет пошустрее.
По крайней мере я бы сделал так как я описал.




Butch, откуда такое стремление сэкономить несколько байт на запись, в колосальный ущерб производительности. Хотел написать полный ответ, но bleed пару постами выше уже практически всё сказал. Т.е. представь, у тебя есть телевизоры с д/у и без него. Сделав соотв. выборку по таблице и имея индекс по этому полю, ты быстро получишь tv с д/у или без. В противном же случае ты заставишь бд считать ВСЕ (это ключевое слово) записи, произвести с ними битовые операции, и выдать тебе отфильтрованный результат.
Имея таблицу в 100 записей это особо не почувствуешь разницу, но при увеличении объёма хранимой информации, производительность будет резко падать.

K началу

 
Информация о пользователе SeRu


Зарегистрирован: 23.07.02
Сообщения: 329
Ссылка на сообщениеДобавлено: 25/04/04 в 14:28     

То есть всё-таки советуете создавать дополнительно 8-15 полей в базе?

K началу

 
Информация о пользователе Jark


Зарегистрирован: 05.01.04
Сообщения: 92
Ссылка на сообщениеДобавлено: 25/04/04 в 15:54     

тебе оптимизация для чего нужна? для скорости или простоты работы?
вряд ли ты делаешь CJ под TV трафик ;)

K началу

 
Информация о пользователе Ru


Зарегистрирован: 17.04.04
Сообщения: 14
Ссылка на сообщениеДобавлено: 25/04/04 в 16:06     

Это будет нихрена не универсальный вариант. Если например добавится еще 10 характеристик, придется базу менять. А это не есть гуд.
Я бы сделал так

1-я таблица
table tv
id int NOT NULL AUTO_INCREMENT PRIMARY KEY,
desc varchar(255)
можно добавить еще полей, которые будут относиться только к этому телеку, например картинку или еще что

2-я таблица
table feature
id int NOT NULL AUTO_INCREMENT PRIMARY KEY,
desc varchar(255)
можно также здесь добавить поля, например история появления этой возможности в телевизорах icon_smile.gif

3-я таблица - связка между двумя предыдущими
table tv2feature
id int NOT NULL AUTO_INCREMENT PRIMARY KEY,
tv_id int NOT NULL,
feature_id NOT NULL,
UNIQUE (tv_id,feature_id),
INDEX tv (tv_id)

тогда получается неограниченное количество описаний товара (features)
для показа информации по нужному телевизору делаешь
select tv.desc as 'tv_desc', feature.desc as 'feature_desc'
from tv left join tv2feature on tv2feature.tv_id=tv.id
left join feature on feature.id=tv2feature.feature_id
where tv.id='ид нужного тебе телека'

вот, что скажешь? icon_smile.gif

K началу

 
Информация о пользователе SeRu


Зарегистрирован: 23.07.02
Сообщения: 329
Ссылка на сообщениеДобавлено: 25/04/04 в 16:56     

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

K началу

 
Информация о пользователе sexvendor


Зарегистрирован: 07.10.03
Сообщения: 66
Ссылка на сообщениеДобавлено: 25/04/04 в 17:05     

Ru писал:
Это будет нихрена не универсальный вариант. Если например добавится еще 10 характеристик, придется базу менять. А это не есть гуд.
Я бы сделал так
1-я таблица
table tv
id int NOT NULL AUTO_INCREMENT PRIMARY KEY,
desc varchar(255)
можно добавить еще полей, которые будут относиться только к этому телеку, например картинку или еще что
2-я таблица
table feature
id int NOT NULL AUTO_INCREMENT PRIMARY KEY,
desc varchar(255)
можно также здесь добавить поля, например история появления этой возможности в телевизорах icon_smile.gif
3-я таблица - связка между двумя предыдущими
table tv2feature
id int NOT NULL AUTO_INCREMENT PRIMARY KEY,
tv_id int NOT NULL,
feature_id NOT NULL,
UNIQUE (tv_id,feature_id),
INDEX tv (tv_id)
тогда получается неограниченное количество описаний товара (features)
для показа информации по нужному телевизору делаешь
select tv.desc as 'tv_desc', feature.desc as 'feature_desc'
from tv left join tv2feature on tv2feature.tv_id=tv.id
left join feature on feature.id=tv2feature.feature_id
where tv.id='ид нужного тебе телека'
вот, что скажешь? icon_smile.gif



Хороший вариант, только не много не правильно третья таблица сделана. Лучше так:

tv_id int unsigned NOT NULL,
feature_id int unsigned NOT NULL,
PRIMARY KEY (tv_id,feature_id)

Так же сделать тип этих трёх таблиц InnoDB (на сколько можно предположить что речь идёт о MySQL) и создать внешние ключи.

K началу

 
Информация о пользователе Butch


Зарегистрирован: 14.09.03
Сообщения: 92
Ссылка на сообщениеДобавлено: 25/04/04 в 19:52     

sexvendor писал:
Butch, откуда такое стремление сэкономить несколько байт на запись, в колосальный ущерб производительности. Хотел написать полный ответ, но bleed пару постами выше уже практически всё сказал. Т.е. представь, у тебя есть телевизоры с д/у и без него. Сделав соотв. выборку по таблице и имея индекс по этому полю, ты быстро получишь tv с д/у или без. В противном же случае ты заставишь бд считать ВСЕ (это ключевое слово) записи, произвести с ними битовые операции, и выдать тебе отфильтрованный результат.
Имея таблицу в 100 записей это особо не почувствуешь разницу, но при увеличении объёма хранимой информации, производительность будет резко падать.

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

K началу

 
Информация о пользователе SeRu


Зарегистрирован: 23.07.02
Сообщения: 329
Ссылка на сообщениеДобавлено: 25/04/04 в 21:08     

Для меня очень актуально. Как я понял из дискуссии есть 3 метода.
1) База с полями
2) База с 1 универсальным полем
3) Разбить базу на различные таблицы

K началу

 
Текстовая реклама в форме ответа
Заголовок и до четырех строчек текста
Длина текста до 350 символов
Купить рекламу в этом месте!
Внимание! В связи с устареванием топика эта страница была взята из кэша.

Спонсор раздела Стань спонсором этого раздела!

Реклама на сайте Advertise with us

Опросы

Рецепт новогоднего блюда 2022



Обсудите на форуме обсудить (11)
все опросы »