faqs.org.ru

 Главная > Программирование > Работа с базами данных >

Borland Interbase 5 FAQ

Секция 1 из 3 - Предыдущая - Следующая
Все секции - 1 - 2 - 3

Borland IB Database FAQ
Borland ИнтерБэйз Q&A, версия 2.02 от 31 мая 1999
последняя редакция от 17 ноября 1999 года.
Часто задаваемые вопросы и ответы по Borland IB Database
Материал подготовлен в Демо-центре клиент-серверных технологий. (Epsylon Technologies)
Материал не является официальной информацией компании Borland.
E-mail ib@demo.ru
www: http://ib.demo.ru
Телефоны: 095-535-0319 (Зеленоград)
535-5349
913-5608 (Водный Стадион)
913-2934
Источники: Borland International, Борланд АО, релиз IB Database 4.0, 4.1, 4.2, 5.0, 5.1, 5.5, 5.6, различные источники на WWW-серверах, текущая переписка, московский семинар по Delphi и конференции, листсервер ESUNIX1, листсервер mers.com.

Cоставители: Дмитрий Кузьменко

Этот документ содержит наиболее часто предоставляемую информацию по Borland IB Database.
   

1.1 Работает-ли IB с русскими буквами ?
1.2 Я установил Delphi 2.0 C/S, но почему-то использование русских кодировок приводит к ошибке ?
1.3 Почему таблица или select показываетс в Grid быстро, а перемещение в конец таблицы происходит долго ?
1.4 Как я могу работать с IB с клиентского компьютера ?
1.5 В каких версиях IB поддерживаются уведомлени о событиях (Event Alerts) ?
1.6 Сколько памяти использует IB на сервере ?
1.7 У меня возникают проблемы с открытием базы данных. USERNAME и PASSWORD вроде-бы правильные.
1.8 Можно-ли создать пользователя БД при помощи SQL-команды ?
1.9 Что такое ISC4.GDB ? Для чего нужна эта БД ?
1.10 Я создал БД с правами пользователей в Local IB. После переноса этой БД на IB for NT все пользователи куда-то "пропали". В чем дело ?
1.11 Как переносить базы данных между разными IB ? Например между Local IB и IB for NetWare ?
1.12 Почему IB работает неустойчиво на NetWare 4.x ?
1.13 Включение WAL на NetWare ухудшает производительность на 80% при вставках записей, и только на 15% - при обновлениях. Почему ?
1.14 Есть-ли способ восстановить несохраненные (uncommitted) изменения БД, например в случае отключения питания ?
1.15 Можно-ли в запросах делать поиск по BLOB ?
1.16 Почему я при вополнении запросов получаю "ошибку при создании файла 'SAA.AAA' ?
1.17 Можно-ли создать индекс по полю view ?
1.18 Почему в операторе SELECT для VIEW нельзя использовать ORDER BY ?
1.19 Как оптимизировать запросы ?
1.20 Какой максимальный размер базы данных IB ?
1.21 Сколько БД я могу открыть в одной транзакции ?
1.22 Сколько таблиц может быть в одной БД ?
1.23 Сколько строк и столбцов может быть у одной таблицы ?
1.24 Сколько индексов может быть в БД или у таблицы ?
1.25 Сколько событий можно вызвать из одной процедуры или триггера ?
1.26 Сколько таблиц можно объединять в join?
1.27 Сколько уровней вложенности может иметь запрос ?
1.28 Сколько полей можно использовать в одном составном (композитном) индексе ?
1.29 Какая глубина рекурсии допустима для триггеров или хранимых процедур ?
1.30 Какой максимальный размер текста хранимой процедуры или триггера?
1.31 Сколько UDF и фильтров blob можно определить для одной БД ?
1.32 Сколько клиентов могут зарегистрироваться на одно событие ?
1.33 Как освободить ресурсы, занятые IB ?
1.34 Как осуществить referental integrity между разными БД ? Или как связать таблицы из разных БД ?
1.35 Как скопировать данные между БД ?
1.36 Как конвертировать разные наборы символов ?
1.37 Поддерживает-ли IB репликацию и интерфейс X/Open XA ?
1.38 Можно-ли использовать имя таблицы как параметр хранимой процедуры ?
1.39 Может-ли IB шифровать данные в БД или при передаче по сети ?
1.40 Как определить дисковое пространство, необходимое для хранения БД ?
1.41 Как выбрать размер страницы БД ?
1.42 "Архитектура множественных поколений записи" приводит иногда к странным результатам - большое количество update без commit "тормозит" некоторые другие запросы, пока для БД не сделать "sweep". В чем причина ?
1.43 Поддерживает-ли IB поля типа autoincrement ?
1.44 На каком языке пишутся хранимые процедуры ?
1.45 Как сделать модуль UDF видимым IB ?
1.46 Есть-ли в IB функция SUBSTR и вообще, почему в IB так мало встроенных функций ?
1.47 Как можно создавать UDF ? (определяемые пользователем функции)
1.48 Что такое SHADOW в IB ?
1.49 Как посмотреть содержимое или обновить теневую (shadow) БД ?
1.50 Почему после выдачи Commit или RollBack при открытых таблицах или запросах они перечитываются полностью ?
1.51 Как избавиться от ошибки "multiple rows in singleton select" ?
1.52 Что такое "метаданные" ?
1.53 Где IB хранит информацию о метаданных ?
1.54 Почему невозможно использовать домены (DOMAIN) в хранимых процедурах ?
1.55 После удаления хранимой процедуры невозможно удалить таблицы, использовавшиеся в этой процедуре.
1.56 Как получить QUERY PLAN при работе с IB API ?
1.57 Мне нужны временные таблицы, но их нет в IB. Что делать ?
1.58 Что такое "глубина индекса" (index depth), показываемая в Database Analysis?
1.59 Как часто нужно делать Database Sweep ?
1.60 Запрос с вычислением максимального (MAX) значения работает медленно.
1.61 Можно-ли использовать stored procedures во view
1.62 Ошибка "low volume of metadata change" или Как часто можно менять метаданные (например изменять структуру таблиц)?
1.63 Многоверсионность метаданных, или как поддерживается модификация структур таблиц.
1.64 Почему рекомендуется периодически делать backup/restore ?
1.65 Как работает многоверсионность записей ?
1.66 Какие блокировки обеспечивает IB ?
1.67 Существуют-ли в IB блокировки по чтению ?
1.68 Какие уровни изоляции поддерживает IB ?
1.69 С какими транзакциями работают BDE, WISQL ... ?
1.70 Можно-ли управлять параметрами транзакций IB из BDE ?
1.71 Что такое BLR ?
1.72 Что такое UDF ?
1.73 Не восстанавливаются (restore) процедуры (sp) с QUERY PLAN. Что делать ?
1.74 Почему Server Manager не показывает Database Connections на WinNT ?
1.75 Что такое архитектура SuperServer ?
1.76 Соответствует-ли реализация SQL в IB стандарту ANSI и какому ?
1.77 Можно-ли поместить GDB-файл на другой компьютер ?
1.78 В чем разница между OAT и OIT ? (старейшей активной и старейшей заинтересованной транзакцией).
1.79 В чем разница между CHAR и VARCHAR ? Что лучше использовать ?
1.80 Можно-ли поместить БД IB на CD-ROM ?
1.81 Как выполнить create procedure/trigger при помощи TQuery?
1.82 Как установить генератор в нужное значение в процедуре или триггере?
1.83 Не могу подсоединиться к IB из под web-сервера IIS, Netscape, Baikonur и др
1.84 Ошибка при установке "Internal error near IBcheck"
 
1.1 Работает-ли IB с русскими буквами ?

Да, как с кодировкой 866 так и с 1251, как из Delphi 1.0, так и из Delphi 2.0. Для того, чтобы в БД в строковых полях использовались русские буквы, необходимо при создании БД указать в качестве дополнительного параметра фразу:

DEFAULT CHARACTER SET WIN1251

А в BDECFG32 в драйвере IB и его псевдонимах (aliases) указать языковый драйвер Pdox ANSI Cyrillic. Такие установки обеспечат нормальную работу с кодировкой 1251. (в TDatabase.Params этот языковый драйвер указывается как LANGDRIVER=ancyrr).

Дополнительно, если вы предполагаете использовать выражение UPPER в SQL запросах, то Вам потребуется при создании таблиц IB использовать уточнение COLLATION SEQUENCE для строковых полей.

К сожалению, установить COLLATE PXW_CYRL по умолчанию для базы данных невозможно (такой параметр отсутствует). Поэтому таблицы IB, созданные при помощи Database Desktop или компонента TTable не будут иметь правильного COLLATE для работы с функцией SQL UPPER. (Эта проблема, необходимо отметить, не относится к работе с регистром русских букв внутри Delphi, поскольку для этого внутри VCL используются функции Windows, правильно переводящие буквы кодировки 1251 в верхний регистр и обратно.)

Например, если возможен запрос такого типа:

SELECT * FROM CUSTOMERS
WHERE UPPER(NAME) = 'ИВАНОВ'

То таблицу CUSTOMERS придется создавать при помощи текста

CREATE TABLE CUSTOMERS (
ID INTEGER NOT NULL,
NAME CHAR(30) COLLATE PXW_CYRL,
PRIMARY KEY (ID))

фраза COLLATE PXW_CYRL заставляет IB использовать таблицу трансляции символов PXW_CYRL вместо WIN1251 (которая устанавливается по умолчанию для DEFAULT CHARACTER SET WIN1251).

Однако можно использовать указание порядка сортировки "на ходу", без указания порядка сортировки в описании таблицы - при помощи того-же спецификатора COLLATE. В этом случае запросы могут выглядеть следующим образом:

SELECT * FROM CUSTOMERS
WHERE UPPER(NAME COLLATE PXW_CYRL) = 'ИВАНОВ'

Учтите, что если Вы используете ORDER BY NAME, то порядок записей у полей с COLLATE PXW_CYRL будет отличаться от имеющих только CHARACTER SET WIN1251. В этом случае необходимо и в ORDER BY указывать COLLATE. Например

SELECT * FROM CUSTOMERS
WHERE UPPER(NAME COLLATE PXW_CYRL) = 'ИВАНОВ'
ORDER BY NAME COLLATE PXW_CYRL

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

INSERT INTO MYTABLE VALUES (1, _win1251 'Привет!').

К сожалению, такой способ приводит к тому, что со стандартными компонентами TTable и TQuery можно работать только используя дополнительный компонент UpdateSQL (который позволяет переопределить запросы выдаваемые этими компонентами при INSERT, UPDATE, DELETE, и кроме этого присутствует только в Delphi 2.0).

ODBC-драйвер, поставляемый в дистрибутиве IB 5.5 позволяет указать кодировку win1251 для алиаса, при этом никаких манипуляций с _win1251 не требуется.

1.2 Я установил Delphi X.0 C/S, но почему-то использование русских кодировок приводит к ошибке ?

Проблемы с созданием БД с кодировкой WIN1251 могут быть если у Вас бета-версия Delphi. Еще одна причина - пробелы в имени каталога, в котором
находятся файлы локального IB (Program Files\Borland\Delphi X.0\IntrBase), или база данных (gdb-файл).

Если вам не хочется переустанавливать IB, то вы можете сделать следующее:

  • предварительно выгрузив локальный IB (если он виден на TaskBar), переместите каталог IntrBase в каталог, не содержащий в имени пробелов или на диск C: (C:\IntrBase).
  • Запустите RegEdit. В Registry реально к IB имеют отношение две строки: автоматический запуск Local IB и путь к файлу лицензии IB.
  • Найдите эти две строки и измените путь в этих строках на новый.

  • 1.3 Почему таблица или select показывается в Grid быстро, а перемещение в конец таблицы происходит долго ?

    Когда вы открываете набор данных при помощи TTable, BDE производит fetch только такого количества записей, которые помещаются в Grid. Если вы захотели переместиться в конец таблицы, то для большинства SQL-серверов возможно перемещение по записям только вперед - т.е. если вам потребуется поместить указатель в середину таблицы то BDE пришлось-бы заново перечитывать записи с ее начала. Причина такой работы в том, что SQL-серверы в большинстве возвращают результаты запросов в виде последовательных наборов записей. В навигационных БД напротив, возможно физическое позиционирование на любую запись таблицы.

    Если SQL-сервер поддерживает двунаправленные скроллируемые курсоры, то полное кэширование записей запроса выполняться BDE не будет.

    Кроме этого, TTable и TQuery работают по разному. TQuery при перемещении в конец таблицы действительно сделает выборку всех записей, т.к. он и не может иначе - для выполнения задано конкретное SQL-выражение.

    TTable-же напротив, показывает всю таблицу, и запросы для получения содержимого таблицы формируются автоматически. Поэтому TTable при нажатии вами в TDBGrid клавиш Ctrl-End сформирует запрос типа

    SELECT * FROM TABLE ORDER BY INDEXFIELD DESC

    и покажет только видимые в DBGrid записи "с конца". При этом, если нет DESC индекса по полю INDEXFIELD, сортировка данных (ORDER BY) будет производиться на диске. И чем больше записей в таблице, тем дольше. Для того, чтобы перемещение по Ctrl-End для TTable происходило быстро, нужно создать DESC индекс по полю сортировки. В этом случае операцию перехода в конец таблицы TTable выполнит практически мгновенно. Пользователи Delphi C/S могут посмотреть операторы, выдаваемые TTable SQL-серверу при помощи SQL Monitor.

    1.4 Как я могу работать с IB с клиентского компьютера ?

    Можно использовать IB API (либо наборы компонт FreeIBComponents, IBObjects или IBX, работающие напрямую с IB API), BDE+SQL Links, либо ODBC-драйвер.
    Схема обмена данными между этими компонентами следующая

    GDS32.DLL->IB прямое обращение к IB API
    ODBC->GDS32.DLL-> IB работа через ODBC
    BDE->SQL Link->GDS32.DLL->IB работа через BDE
    BDE->ODBC->GDS32.DLL->IB работа через BDE, ODBC вместо SQL Link.

    Практически во всех случаях вам не требуется производить какие-либо специфические настройки.

    1.5 В каких версиях IB поддерживаются уведомления о событиях (Event Alerts) ?

    Во всех, кроме локального IB для Windows 3.1. Это очень сильно урезанная версия IB, даже по сравнению с Local IB 4.1 for Windows95.
    Устойчивая работа Event Alerters зависит как от используемого компонента (см. ib.demo.ru/download.htm), так и от сервиспаков, установленных на NT Server или Workstation. Например, уведомление о событиях работает, если
    установлен SP3 и postsp3 hotfix TEARDROP2,
    либо установлен SP4 (большой, т.е. ~70мегабайт).

    EventAlerters могут работать неустойчиво, если для SP3 не установлен teardrop2, либо вообще не работать, если установлен SP4 размером ~32 мегабайта (из-за версии tcpip.sys). Если клиентами являются NT Workstation, настоятельно рекомендуется на клиентах установить тот же SP и постфиксы, что и для сервера.

    1.6 Сколько памяти использует IB на сервере ?

    Минимально при запуске - от 1.2 до 3 Мб, далее память распределяется динамически в зависимости от запросов, выполняемых клиентами (от 40 до 400К на клиента). Кроме этого, объем используемой памяти сильно зависит от архитектуры сервера (IB 4.0 и IB 4.2, IB 5.x для NT и IB 5.x для Linux), размера кэша страниц БД и других настроек. Подробнее по настройкам см. PERFORM.HLP в каталоге INTRBASE\BIN

    1.7 У меня возникают проблемы с открытием базы данных. USERNAME и PASSWORD вроде-бы правильные.

    Может быть, что в момент ввода пароля клавиатура переключена в режим Caps Lock - а пароль является регистрочувствительным. После установки действуют имя пользователя SYSDBA и пароль masterkey. Они предназначены для работы Администратора БД. Из соображений security вы должны изменить пароль masterkey, чтобы никто кроме вас не смог подсоединиться к IB. Также, ни в коем случае нельзя удалять пользователя SYSDBA, иначе вы потеряете доступ к системным таблицам.

    1.8 Можно-ли создать пользователя БД при помощи SQL-команды ?

    Нет. Единственно правильный способ - использовать Server Manager. (Tasks | User Security), либо утилиту командной строки GSEC, либо IB user API (для IB 5.x). См. ib.demo.ru/download.htm, www.borland.com/devsupport/bde/.

    1.9 Что такое ISC4.GDB ? Для чего нужна эта БД ?

    БД ISC4.GDB используется IB для хранения информации о пользователях (имена, пароли и т.п.). Удалять этот файл нельзя. Вы можете создать alias на эту БД и посмотреть ее содержимое, но программно не сможете создавать или изменять пользователей поскольку шифрация и дешифрация пароля выполняется IB.

    1.10 Я создал БД с правами пользователей в Local IB. После переноса этой БД на IB for NT все пользователи куда-то "пропали". В чем дело ?

    Причина в том, что информация о пользователях IB хранится в специальном файле ISC4.GDB, и является общей для всех БД на конкретном компьютере. Очевидно что в вашем случае на сервере IB for NT отсутствовали пользователи, заведенные вами для Local IB. Вам придется создать всех ваших пользователей и для IB for NT (при помощи Server Manager). То же самое будет и при переносе базы данных между серверами IB. Т.е. на обоих серверах пользователи должны быть созданы отдельно.

    Если версии IB и платформы на обоих серверах совпадают, то ISC4.GDB можно просто скопировать. Разумеется, при отсутствии подсоединений. (еще лучше вообще выключить сервер БД на время копирования isc4.gdb).

    Перенести isc4.gdb между платформами можно следующим способом: сделать backup isc4.gdb, восстановить на нужном сервере эту БД в другое имя (например isc4_new.gdb), остановить сервер IB, удалить старую isc4.gdb и переименовать isc4_new.gdb.

    1.11 Как переносить базы данных между разными IB ? Например между Local IB и IB for NetWare (Linux)?

    Для переноса нужно использовать операцию backup/restore, т.к. формат хранения данных для разных платформ разный. Переносить БД без backup/restore можно только в том случае, если у IB-источника и IB-приемника совпадает версия ODS - OnDisk Structure. Версию ODS можно увидеть в Server Manager после подсоединения к БД и вызову пункта меню Tasks/Database Statistics (Database Header, ODS version). Как правило, даже у одной и той же версии IB, но для разных операционных систем версия ODS разная.

    1.12 Почему IB работает неустойчиво на NetWare 4.x ?

    Для NetWare 4.x нужно использовать IB 4.2.2. Предыдущие версии IB for Netware сертифицированы только для NetWare 3.11/3.12.
    Для NetWare 5.x выпущена версия IB 5.6.

    1.13 Включение WAL на NetWare ухудшает производительность на 80% при вставках записей, и только на 15% - при обновлениях. Почему ?

    Файл WAL должен быть расположен на другом винчестере чем основная БД. (это-же относится и к теневой БД). В этом случае ухудшения производительности не будет. Кроме этого вы должны учитывать, что запись в WAL происходит синхронно с БД, поэтому сравнивать "производительность" WAL с асинхронными изменениями в БД некорректно.

    1.14 Есть-ли способ восстановить несохраненные (uncommitted) изменения БД, например в случае отключения питания ?

    Нет. Такие изменения будут потеряны. Т.е. БД останется в состоянии, соответствующем последней подтвержденной (committed) транзакции. Несохраненные данные в БД останутся в виде "осиротевших" страниц, которые можно очистить при помощи Server Manager, пункт меню Validate Database, или в виде "мусорных" версий записей, которые будут очищены при очередном чтении данных.

    Вполне возможно, что этот вопрос вызван тем, что восстановление состояния БД в IB отличается от других широкораспространенных SQL-серверов (Oracle, Informix, ...). IB не требует выполнения каких-то специфических действий для продолжения работы с БД в случае сбоя питания - изменения, происходящие до COMMIT, не записываются на место актуальных данных (т.е. отсутствует режим Dirty Read), поэтому они будут просто потеряны, а БД останется в рабочем состоянии.

    примечание: считается что транзакция - логический блок действий, переводящий БД из одного целостного состояния в другое. Поэтому даже если сервер позволяет восстановить uncommitted изменения, то делать этого не стоит.

    1.15 Можно-ли в запросах делать поиск по BLOB ?

    Да. Поиск по строковым (CHAR, VARCHAR) полям или по BLOB можно производить при помощи операторов CONTAINING, STARTING WITH и LIKE. Например

    SELECT * FROM MYTABLE
    WHERE BLOBFIELD CONTAINING 'sometext';

    Поиск по умолчанию считается case-insensitive (регистро-нечувствительный), поэтому для латинских букв строку поиска можно задавать строчными буквами (в нижнем регистре). В этом случае при поиске 'sometext' в ответ войдут записи с 'sometext', 'SOMETEXT' и 'SomeText'. К сожалению, для BLOB невозможно указать COLLATE для правильного перевода русских букв в верхний регистр, поэтому поиск слов, содержащих русские буквы, будет производиться только по точному совпадению.

    При поиске подтип BLOB (SUB_TYPE 0 или 1 - текст или binary) не имеет значения, т.к. подтип имеет значение только для приложения, или для фильтров BLOB. BLOB-ы разных подтипов хранятся абсолютно одинаковым способом.

    1.16 Почему я при вополнении запросов получаю "ошибку при создании файла 'SAA.AAA' ?

    Этот файл является временным, и создается когда при выполнении запроса возникает необходимость в сортировке результата. Ошибка может возникать при нехватке дискового пространства на томе, куда указывает TEMP. Для NT при работе IB в режиме сервиса необходимо изменить переменную TEMP для System (см. My Computer/Properties/Environment). Для IB 5.x можно указать диски и размер временных файлов в файле конфигурации IBCONFIG, или в переменной окружения INTERBASE_TMP (см. Operations Guide, стр92). Например:

    TMP_DIRECTORY "c:\" 10000000
    TMP_DIRECTORY "e:\temp\" 100000000
    Может быть указано несколько дисков или каталогов, которые будут использоваться последовательно. Размер должен быть указан в байтах. Кавычки для имени диска и каталога обязательны.

    1.17 Можно-ли создать индекс по полю view ?

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

    Если вы хотите использовать индексы в компоненте TTable, то делать это нужно не через свойство IndexName, а указывая поле, по которому вы хотите отсортировать таблицу или view, непосредственно в свойстве IndexFieldNames. SQL-сервер сам разберется, есть-ли по такому полю индекс, и сможет-ли он использовать его для ускорения обработки запросов.

    1.18 Почему в операторе SELECT для VIEW нельзя использовать ORDER BY ?

    Вообще независимо от наличия индексов записи в таблице располагаются в том порядке, в котором они добавлялись. Поскольку view представляет из себя "виртуальную" таблицу, то записи также должны быть представлены в произвольном порядке.

    1.19 Как оптимизировать запросы ?

    Вот несколько простых рекомендаций для оптимизации запросов:

  • избегайте явного использования outer join
  • используйте неявный join (select a,b, from a1, b1 where ...) вместо явного.
  • пробуйте разный порядок таблицы в запросе для получения оптимальной производительности (также и для явного join)
  • пробуйте ваши запросы в WISQL, включив Show Query Plan и Show Statistics.
  • используйте индексы по полям, участвующим в условиях where.
  • не забывайте делать SET STATISTICS по индексам, созданным вами специально для ускорения запросов.
  • К сожалению, не существует точных правил по оптимизации запросов - это путь проб и ошибок, т.к. невозможно заранее предсказать ни ваши запросы, ни ваши реальные данные.

    примечание: бывают ситуации, когда оптимизатор "настаивает" на использовании всех индексов по определенному столбцу, даже если создан специальный композитный индекс по всем полям where. В этом случае необходимо принудительно заставить оптимизатор IB использовать нужный запрос, причем скорость отработки такого запроса может ускориться в 10 раз.

    Секция 1 из 3 - Предыдущая - Следующая

    Вернуться в раздел "Работа с базами данных" - Обсудить эту статью на Форуме
    Главная - Поиск по сайту - О проекте - Форум - Обратная связь

    © faqs.org.ru