Страница 1 из 1

Не создается индекс по полю VARCHAR(254)

Добавлено: 22 дек 2014, 18:22
Дмитрий
Доброго дня!
Имеем Interbase 2009, размер страницы БД 16384, в таблице codepage win1251, collate win1251.
В таблице есть поле FULL_NAME VARCHAR(254). По этому полю пытаюсь создать индекс. В результате получаю сообщение "key size exceeds implementation restriction for index". Вроде как размер индекса не должен быть больше 1/4 размера страницы БД? Или я ошибаюсь? В чем проблема?
P.S. Максимальный размер поля, по которому мне удалось создать индекс, VARCHAR(136).

Re: Не создается индекс по полю VARCHAR(254)

Добавлено: 22 дек 2014, 22:43
kdv
Вроде как размер индекса не должен быть больше 1/4 размера страницы БД?
В Firebird - с версии 2.0. В InterBase - с версии XE.

Re: Не создается индекс по полю VARCHAR(254)

Добавлено: 23 дек 2014, 09:40
Дмитрий
kdv писал(а):
Вроде как размер индекса не должен быть больше 1/4 размера страницы БД?
В Firebird - с версии 2.0. В InterBase - с версии XE.
А в версии 2009?

Re: Не создается индекс по полю VARCHAR(254)

Добавлено: 23 дек 2014, 12:02
kdv
версия XE появилась позже 2009. Я удивлен, что нужно об этом сообщать :-)

на всякий случай
http://www.ibase.ru/devinfo/allversions.htm

Re: Не создается индекс по полю VARCHAR(254)

Добавлено: 23 дек 2014, 12:35
Дмитрий
kdv писал(а):версия XE появилась позже 2009. Я удивлен, что нужно об этом сообщать :-)
Да это я знаю, не совсем тупой :-) Вопрос был о максимальном размере текстового поля, по которому можно построить индекс в Interbase 2009!

Re: Не создается индекс по полю VARCHAR(254)

Добавлено: 23 дек 2014, 15:12
kdv
надо было конкретизировать :-)
пока не стало 1/4 размера страницы, всегда было, например для win1251 (это двухбайтовый чарсет) - 252 байта без collate, 84 байта с collate, и тут размер страницы не влияет.
Обращаю внимание, что символы могут состоять из нескольких байт, например, в UTF8 (поддерживается и в ИБ, и в ФБ) с этим делом еще хуже, т.е. нужно макс. размер делить на 4, в том числе даже если размер ключа 1/4 страницы в новых версиях.

www.ibase.ru/devinfo/ibrusfaq.htm
www.ibase.ru/unicode_faq.html

если используется utf8 да еще с collate, то размер символа в ключе получается 6 байт, а не 4.
http://www.sql.ru/forum/892796/pagesize ... ar-169-why

Re: Не создается индекс по полю VARCHAR(254)

Добавлено: 23 дек 2014, 16:20
Дмитрий
Что-то я совсем запутался... У меня win1251 c collate. Опытным путем подобрал размер поля varchar(136). Индекс создался, backup восстанавливается, все хорошо. Вот эти 136 символов я никак не могу увязать ни с 252-я байтами, ни с 84-я. Где я ошибаюсь? Тогда по логике, с collate и win1251 у меня максимальный размер поля в индексе должен быть 84 символа, а у меня 136?

Re: Не создается индекс по полю VARCHAR(254)

Добавлено: 23 дек 2014, 17:13
kdv
collate win1251 - это нонсенс. upper работает только в collate pxw_cyrl, а коллэйт win1251 "пустой". Поэтому его надо убирать.
максимальный размер поля в индексе должен быть 84 символа, а у меня 136?
84 - для collate pxw_cyrl. поскольку вы влепили пустопорожний коллэйт win1251, у вас 136. А могло бы быть и 252, если уберете коллэйт. Откуда вы его взяли, кстати? я не припомню, чтобы кто-нибудь когда-либо советовал этот коллэйт использовать.

Re: Не создается индекс по полю VARCHAR(254)

Добавлено: 25 дек 2014, 11:26
Дмитрий
поскольку вы влепили пустопорожний коллэйт win1251, у вас 136. А могло бы быть и 252, если уберете коллэйт. Откуда вы его взяли, кстати? я не припомню, чтобы кто-нибудь когда-либо советовал этот коллэйт использовать.
Я его не указывал. Он отображается при создании поля в IBExpert-е. Однкао, если посмотреть скрипт, то там будет

Код: Выделить всё

FULL_NAME     VARCHAR(252)
а если коллэйт указать, то будет

Код: Выделить всё

FULL_NAME     VARCHAR(252)  COLLATE PXW_CYRL
Отсюда делаю вывод, что коллэйт WIN1251 просто отображается в интерфейсе IBExpert-а, а фактически он не указан. Тогда не ясно, почему по полю размером в 137 символов индекс уже не строится.

Re: Не создается индекс по полю VARCHAR(254)

Добавлено: 25 дек 2014, 14:51
kdv
вы где-то говорите неправду.
Только что на IB 2009 сделал:
1. создал базу в win1251
2. создал таблицу со столбцом name1 varchar(252)
3. создал индекс по name1

Код: Выделить всё

CREATE TABLE X (
    ID     INTEGER NOT NULL,
    NAME1  VARCHAR(252));

ALTER TABLE X ADD CONSTRAINT PK_X PRIMARY KEY (ID);
CREATE INDEX BYNAME1 ON X (NAME1);
никаких ошибок.

p.s. рекомендую проверять такие вещи самостоятельно, на пустой базе, это занимает 1-2 минуты вашего времени, не чужого.