adsl club

Справочник

Форум

Программы

Фильмы

Ресурсы

Файлообмен

Хостинг

Ростелеком
Отношение "много ко многим" между одной и той же таблицей в MS SQL Server Compact (.NET Framework 3.5)
Ответить на тему    Форум АДСЛ КлубаЦИФРОВОЙ ФЛЕЙМ :)ПРОГРАММИРОВАНИЕ
Автор Сообщение
AlexRock
Гуру
СообщениеДобавлено: Пн 13-07-09 : 11-08    Заголовок сообщения: Отношение "много ко многим" между одной и той же таблицей в MS SQL Server Compact (.NET Framework 3.5) Ответить с цитатой

Есть таблица Herbicide (гербициды, по-русски). Суть в том, что есть гербициды, которые могут взаимодействовать друг с другом, а есть те, которые не могут. Так вот, нужно представить в базе данных (БД) таблицу отношений, в которой нужно каждому гербициду поставить в соответствие список гербицидов, которые могут взаимодействовать с данным гербицидом. В БД это будет выглядеть, как создание отношения "много ко многим" между одной и той же таблицей (т. е. таблица должна ссылаться сама на себя). Известно, что отношение "много ко многим" реализуется через т. н. таблицу связей, которую я назвал TankMedley (баковая смесь).

Таблицы-то я создал, а при создании отношений между ними начали вылезать ошибки. Я пробовал два варианта.

1 вариант. Одно отношение с двумя парами соотносящихся столбцов - см. рисуноки ниже и получившуюся ошибку при попытке добавить отношение (в ошибках - вся соль этой темы):

(далее во всех таблицах столбцы Id - первичные ключи)

схема участка БД:



свойства таблицы TankMedley:



создание отношения:



Тут сказано, что у таблицы, на которую ссылаются (у меня это таблица Herbicide), должен быть первичный ключ (или какой-то кандидат). Но она имеет первичный ключ!

Ладно, тогда попробую другой вариант.

2 вариант. Два отношения, каждое - с одной парой соотносящихся столбцов. Первое отношение добавляется нормально, а второе выдаёт ошибку (см. ниже):

схема участка БД:



создание первого отношения:



создание второго отношения:



Тут сказано, что ссылочное отношение приведёт к созданию циклической ссылки, что непозволимо. Но ведь у меня нет здесь цикла! Цикл бы был, если бы я в разные стороны ссылался в каждом отношении, а тут у меня в одну сторону - к одной таблице - все отношения идут, поэтому при удалении любой строки из таблицы "выше по иерархии" (здесь это Herbicide) у меня удалятся (каскадно) только строки в таблице связей TankMedley, а при удалении любой строки в TankMedley, из Herbicide ничего удаляться не будет. Т. е. цикла нет!

Вобщем, тут получается, что с помощью только двух таблиц я не могу в этой СУБД создать отношение "много ко многим" между одной и той же таблицей. Вместо этого нужно создать другую таблицу - копию таблицы Herbicide - и уже между этими копиями создавать такое отношение при помощи таблицы связей. Но это же дублирование данных!

Проверили в Access - там можно всё это сделать при помощи всего двух таблиц, как я и хотел вначале, но там скрыта от пользователя вся кухня создания отношений и правил удаления/обновления (или мы не знаем, где это делается).

Вобщем, вопрос - это я что-то неправильно делаю, или это MS SQL Server Compact такой ограниченный? Неужели придётся делать таблицу-копию, чтобы достиг желаемого результата?
 Наверх
Посмотреть профиль / Отправить личное сообщение Отправить личное сообщение  
Richard Ferlow
Гуру
Предупреждений : 2
СообщениеДобавлено: Пн 13-07-09 : 11-34    Заголовок сообщения: Ответить с цитатой

Я помню делал как-то так

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

Таким образом для каждого гербицида создается столько записей, сколько он может раз взаимодействовать.

уникальный id записи - чтобы в случае чего к конкретной записи обратиться
 Наверх
Посмотреть профиль / Отправить личное сообщение Отправить личное сообщение   Номер ICQ
AlexRock
Гуру
СообщениеДобавлено: Пн 13-07-09 : 11-52    Заголовок сообщения: Ответить с цитатой

Ричард, это я всё знаю - как делаются связи "много ко многим" и прочую теорию (начальную) я изучал Smile - я так и делаю, как ты говоришь, т. е. создаю таблицу связей, где будет для каждого гербицида столько записей, сколько он может раз взаимодействовать. У меня другая проблема - конкретно эта СУБД (может, и другие такие же - я не проверял, а насчёт Аксесса я у другого человека спросил, который в создании отношений между таблицами там сам не очень понимает) не хочет создавать отношение "много ко многим" между одной и той же таблицей с использованием таблицы связей по всем правилам построения БД. Выдаёт какие-то несуразные ошибки - я эти ошибки опроверг (по-моему).

Вот, хотел бы услышать мнения людей, которые создавали такие отношения и связи - как вы разруливали эту проблему?
 Наверх
Посмотреть профиль / Отправить личное сообщение Отправить личное сообщение  
AlexRock
Гуру
СообщениеДобавлено: Пн 13-07-09 : 14-25    Заголовок сообщения: Ответить с цитатой

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

Есть одна таблица Гербициды и есть другая ТаблицаСвязей, которая связывает Гербициды саму с собой отношением "много ко многим". Пусть ТаблицаСвязей заполнена так:

Id | G1Id | G2Id - айдишники записей в ТаблицеСвязей и двух гербицидов, могущих взаимодействовать.

1 | 1 | 2
2 | 1 | 3
3 | 2 | 3

При удалении из таблицы Гербициды гербицида с айдишником 2 должны удалиться записи 1 и 3 (из столбцов G1Id и G2Id, соответственно) из ТаблицыСвязей по каскадному правилу, но MS SQL Server Compact не даёт сделать это - он может задать каскадное правило только для одного столбца (G1Id или G2Id). Данные по совпадению во втором столбце придётся удалять "вручную" - писать запрос на удаление. Т. е. нельзя добиться автоматического удаления из обоих столбцов.

Ту же ситуацию мы смоделировали в Аксессе - сделали те же таблицы и так же их заполнили. Аксесс удалил каскадом записи из обоих столбцов (точнее, просто сделал поля в записях ТаблицыСвязей пустыми), но не удалил сами записи! Удаление самих записей пришлось делать опять же "вручную".

Похоже, что это недоработки этих СУБД... или мы просто не знаем, как ими пользоваться, чтобы добиться нужных результатов.

Т. е. получается, что накодить-то я могу что угодно - хоть вообще БД "вручную" управлять, но на кой тогда городить целую СУБД, коли она не может автоматически (по созданию правил) решить такую задачу, что я озвучил?... Правда, я поспрашивал у людей (не сильно опытных) - им такие задачи пока не встречались.


Вобщем, у кого ещё есть мысли - буду рад узнать. Smile
Последний раз редактировалось: AlexRock (Пн 13-07-09 : 16-08), всего редактировалось 1 раз
 Наверх
Посмотреть профиль / Отправить личное сообщение Отправить личное сообщение  
Алексей Н
Гуру
СообщениеДобавлено: Пн 13-07-09 : 14-47    Заголовок сообщения: Ответить с цитатой

надо описать таблицу Herbicide дважды, с другим алиасом второй раз.
 Наверх
Посмотреть профиль / Отправить личное сообщение Отправить личное сообщение Отправить e-mail   Номер ICQ
AlexRock
Гуру
СообщениеДобавлено: Пн 13-07-09 : 16-10    Заголовок сообщения: Ответить с цитатой

Алексей Н писал(а):
надо описать таблицу Herbicide дважды, с другим алиасом второй раз.

Я думал об этом, но тогда придётся сделать программно (кодить ручками) синхронизацию данных между этими таблицами-копиями. А ещё это "дублирование данных" - так не учат делать в академических ВУЗах. Smile По-моему, проще "вручную" делать запрос на удаление записи по совпадению во втором столбце при каждом запросе на удаление записи по совпадению в первом столбце.


Меня по-прежнему интересует вариант автоматического каскадного удаления записей по двум отношениям, как я вначале хотел. Ещё на sql.ru поспрошаю.
 Наверх
Посмотреть профиль / Отправить личное сообщение Отправить личное сообщение  
BorPas
Девелопер
СообщениеДобавлено: Пн 13-07-09 : 16-14    Заголовок сообщения: Ответить с цитатой

да нужно не две таблицы, а два алиаса на одну таблицу в запросе написать

пример на SQL
Код:
SELECT t.topic_id FROM phpbb_topics AS t, phpbb_topics AS d WHERE t.topic_moved_id=d.topic_moved_id
 Наверх
Посмотреть профиль / Отправить личное сообщение Отправить личное сообщение Посетить сайт автора  
Алексей Н
Гуру
СообщениеДобавлено: Пн 13-07-09 : 16-46    Заголовок сообщения: Ответить с цитатой

BorPas писал(а):
два алиаса на одну таблицу

вот-вот.
Без использования алиасов ни одну серьезную базу вообще не напишешь, имхо. Во всяком случае там, где есть ограничение на длину текста sql-запроса. Поэтому лучше сразу взять себе за правило присваивать всем таблицам алиасы одно-двухсимвольные, но это уже другой вопрос.
Кстати, насчет каскадного удаления - поосторожнее с ним. Повнимательнее в смысле.
 Наверх
Посмотреть профиль / Отправить личное сообщение Отправить личное сообщение Отправить e-mail   Номер ICQ
Serge
Форумчанин
СообщениеДобавлено: Пн 13-07-09 : 16-50    Заголовок сообщения: Ответить с цитатой

AlexRock писал(а):

Меня по-прежнему интересует вариант автоматического каскадного удаления записей по двум отношениям, как я вначале хотел. Ещё на sql.ru поспрошаю.


А если с помощью тригера на удаление?
 Наверх
Посмотреть профиль / Отправить личное сообщение Отправить личное сообщение  
AlexRock
Гуру
СообщениеДобавлено: Пн 13-07-09 : 19-44    Заголовок сообщения: Ответить с цитатой

Про псевдонимы (алиасы) я что-то не помню - почитаю. Спасибо.

Serge писал(а):
А если с помощью тригера на удаление?

Про триггеры тоже знаю только, что они существуют. Тоже почитаю.
 Наверх
Посмотреть профиль / Отправить личное сообщение Отправить личное сообщение  
AlexRock
Гуру
СообщениеДобавлено: Вт 14-07-09 : 11-01    Заголовок сообщения: Ответить с цитатой

Алексей Н писал(а):
Кстати, насчет каскадного удаления - поосторожнее с ним. Повнимательнее в смысле.

Кстати, MS SQL Server просто не позволяет делать ссылочные циклы (вона, ошибку выдаёт при создании отношения - я вверху картинку привёл), так что неконтролируемого каскадного удаления всех записей в БД, которым пугают в учебниках по БД, не ожидается. Да и иерархия отношений у меня самая простая - там не более двух-трёх таблиц "в глубину" связаны, так что каскадным удалением я много похерить не смогу.
 Наверх
Посмотреть профиль / Отправить личное сообщение Отправить личное сообщение  
Алексей Н
Гуру
СообщениеДобавлено: Вт 14-07-09 : 12-00    Заголовок сообщения: Ответить с цитатой

Не в том дело. Просто бывает так что ставят удаление не подумав (классная фича!), а потом выясняется что оно "тут нужно, а тут не нужно, поэтому надо убрать".
 Наверх
Посмотреть профиль / Отправить личное сообщение Отправить личное сообщение Отправить e-mail   Номер ICQ
Показать сообщения:   
Ответить на тему    Форум АДСЛ КлубаЦИФРОВОЙ ФЛЕЙМ :)ПРОГРАММИРОВАНИЕ Часовой пояс: GMT + 7
Страница 1 из 1

 

 
Аватары: Вкл|Выкл   ЮзерИнфо: Вкл|Выкл   Подписи: Вкл|Выкл
Перейти:  
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете вкладывать файлы
Вы можете скачивать файлы