powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Sybase ASA, ASE, IQ [игнор отключен] [закрыт для гостей] / Foreign Key "1 to 0..1"
4 сообщений из 4, страница 1 из 1
Foreign Key "1 to 0..1"
    #32541798
Dmitriy Popov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
в ASA 9.0.0 нужно сделать внешний ключ "1 к 0..1"

Известно, что ASA индексирует внешние ключи самостоятельно, т.е. после создания внешнего ключа имеем неуникальный индекс. Это дает нам "1 к 0..n".

Повесить на это поле ограничение UNIQUE (т.е. альтернативный ключ) нельзя, ибо тогда null не будут игнорироваться, и получится "1 к 1".

Создавать еще один индекс ломает, т.к. получим 2 индекса, один из которых не нужен. Как измнеить системный индекс, или повлиять на его создание, я тоже не нашел.

Пусть в Table_A первичный ключ PK_ID и внешний ключ из Foreign_ID - тот самый, что надо сделать "1 к 0..1".

Нашел способ обойтись автоматическим индексом и одним ограничением. Вот что у меня окончательно получилось:
Код: plaintext
1.
2.
3.
4.
5.
CONSTRAINT 1_TO_1 CHECK(
Foreign_ID IS NULL OR NOT EXISTS 
(SELECT 'x' 
   FROM (SELECT Foreign_ID AS F_ID, PK_ID AS PK FROM Table_A) AS TA 
  WHERE TA.F_ID = Foreign_ID TA.PK <> PK_ID
))

Внутренний SELECT необходим, ибо любое упоминание Foreign_ID приводит к чтению нового значения, т.к. это имя поля из таблицы.

Это только я так извращаюсь? Или можно сделать проще, и без двойных индексов?
...
Рейтинг: 0 / 0
Foreign Key "1 to 0..1"
    #32541803
Александр Спелицин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В M$ это можно было сделать следующим образом: Создать View как
Select * from MyTable Where id Is Not Null
и повесить уникальный ключ на поле id.
Про ASA не могу сказать, есть ли там возможность индексировать вьюхи :)
...
Рейтинг: 0 / 0
Foreign Key "1 to 0..1"
    #32541888
Фотография ASCRUS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В ASA вешать индексы на представления нельзя. Можно только на вычисляемые поля.

Кстати при создании UNIQUE тоже создается индекс, так что даже если бы и можно было сделать UNIQUE, то все равно получилось бы 2 индекса :)

Вариант с использованием SQL скрипта в CHECK я бы вообще не рекомендовал использовать - при его использовании тормоза гарантированы, т.к. ASA придется вызывать этот скрипт для каждой вставляемой или обновляемой записи. С учетом использования NOT EXISTS, которого никогда не любил оптимизатор ни одной СУБД, кроме накладных расходов СУБД ничего не получим.

Есть конечно вариант сделать AFTER EACH STATEMENT TRIGGER, в котором на весь массив вставляемых или обновляемых записей делать проверку одним запросом, однако тут тоже будут накладные расходы, т.к. СУБД сначала проведет операции записи в таблицу, а в случае возбуждения ошибки в триггере ей придется делать откат.

С учетом всего вышесказанного мое личное мнение: это просто создать уникальный индекс на поле и не задумываться о лишнем индексе. Кстати уникальный индекс наоборот даже будет выгоден, так как оптимизатор уже точно будет знать, что поле в FOREIGN KEY уникально и предпочтет использовать этот индекс вместо своего системного в операциях выборок данных и вполне возможно будет его использовать при операциях изменения данных для проведения блокировок.

P.S. Кстати CHECK единственное место, где булевая логика по своему работает с NULL: любая операция с NULL будет истинна. Т.е. в CHECK можно вместо ((Field IS NULL) OR (Field = 1)) написать (Field = 1).
...
Рейтинг: 0 / 0
Foreign Key "1 to 0..1"
    #32543761
Dmitriy Popov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Спасибо ASCRUS. Значит будем добавлять второй индекс.
...
Рейтинг: 0 / 0
4 сообщений из 4, страница 1 из 1
Форумы / Sybase ASA, ASE, IQ [игнор отключен] [закрыт для гостей] / Foreign Key "1 to 0..1"
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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