Снег Север писал(а):На самом деле никаких проблем нет, просто топикстартер явно не в курсе про элементарные возможности мускула. А генерировать индексы на основе GUID - бггг...
Так и не нужны никакие возможности. См. мой первый пост в топике. Почему нельзя так сделать? А дубликаты GUID'ов на практике возможны разве что при баге в алгортиме их генерации. Используются они обычно не как ID, а как внешний ID.
MySQL, конечно, то еще дермище, но транзакции поддерживает в полном объеме, если только там нет DDL. И что значит возможно? Так обычно и делается. ORM так делает по умолчанию. По-другому собсно и не сделаешь нормально.
Чтобы словить проблемы с дубликатами GUID, нужна система значительных масштабов. Но на таких масштабах без GUID проблем будет еще больше.
Вариант со взятием номера после INSERT тупиковый. Я не буду никого отговаривать от него, потому что этот вариант работает, и я сам много лет его использовал. Но этот вариант не масштабируется и рано или поздно от него придется отказаться.
С ORM дел не имею, а для мускула "нормально" - это как я написал выше. Прекрасно работает на базах размером в гигабайты и с таблицами в десяток миллионов записей. А большего мне пока не требовалось.
Топикстартер в курсе элементарных возможностей mySql, проблема в том, что проект начинался и вырос много лет назаД. когда я еще не курил шаблоны ООП, DDD и прочие "правильные" методы проектирования и программирования. Тогда у меня все строилось как у настоящего дельфиниста - от кучи окошек к куче логики. Поэтому на большой форме есть таблицы, которые отображают напрямую таблицы БД, то есть lookup компоненты. Создав новую запись и не внеся ее еще в БД, я не могу синхронно отобразить в lookup таблице данные связанной таблицы, поскольку в самой БД еще не сохранен ID по которому идет SQL запрос.
Абсолютно не связанные между собой вещи. И вообще - с некоторых пор вообще с очень большой настороженностью отношусь к инструментам разработчики которых заявляют о том что они сами создадут для вас БД. В итоге приходилось полностью с нуля всё переписывать. А уж об качестве сложных запросов к БД - вообще мрак.
Выразился не так. Была такая ситуация. На днях. Надо мне было спроектировать БД. В объектах проектировка напрашивалась сама собой: абстрактный родитель и два (для начала) специфических наследника (основной объект, там еще конечно много вспомогательных). Такая архитектура отлично укладывалась бы и на модель, и на представление. Но как потом в freepascal/lazarus перенести это в БД? Сидеть самому писать ORM, изучать тонны кода tiOPF или другого чего-то? В С# написал классы, запустил entity framework, и получил во-первых готовый DDL для генерации БД, во-вторых все возможности готовой ORM. И занялся делом, а не написанием вспомогательного кода для того, чтобы через месяц подойти к делу. Я уверен, что в лазарусе можно настроить аналогичный маппинг, но на это нужно потратить очень много времени. Зачем это делать лично мне, если есть готовые инструменты в другой среде? Тем более, изучив C#, я выявил кучу других полезных инструментов этого языка и среды visual studio, сокращающих код до той части, которая максимально приближена к конкретной логике конкретного приложения, при этом предоставляя возможность полноценного MVC: так я сразу сделал как WPF представление своей БД, так и web. Я не собираюсь совсем отходить от паскаля, мне очень нравится этот язык, это некоторые другие проекты, не связанные с БД, которые я буду для себя развивать.
Добавлено спустя 4 минуты 10 секунд: И кстати говоря, объектная модель в том числе максимально удобно и просто решает и ту задачу, с которой я начал этот топик.
У нас принципиально разный подход. Ты идёшь от средства разработки морды к БД А я наоборот - сначала рисую БД. И только после того, как вижу, что все укладывается - рисую морду. Просто на мой взгляд - реляционная модель хранения данных более удобная. Проще и гибче настроить. А уж потом, на базе запросов, построить объектную модель на основе датасетов - это просто два раза кликнуть по датасету и создать его поля. Вот чего иногда не хватает в лазаре (и что было ещё в 7-й дельфи) - это быстрое создание форм редактирования датасета - когда можно было просто поля с датасета кинуть в новую форму. И в неё создаются объекты для ввода данных.
alexs писал(а):Ты идёшь от средства разработки морды к БД
теперь уже нет)) сначала я делаю объектную модель данных. первый подход, когда я только начинал, привел меня к тому, что в легаси-проекте ТРИ примерно одинаковых формы с кучей компонентов, ТРИ примерно одинаковых таблицы в БД с примерно одинаковыми полями, незначительно отличающимися друг от друга, при этом две таблицы вообще отличаются только названием и наличием BLOB поля. сегодняшний подход был бы таким: ОДИН родитель, включающий все общие свойства, ТРИ наследника со специфическими свойствами. ОДНА форма, отображающая только то, что ей передаст модуль-контроллер. Маппинг этого в БД предполагает два варианта: или одна общая таблица с полем-спецификатором, или три вспомогательных таблицы и идентификация по общему ID.
Вот как раз не надо бояться что у тебя 3 одинаковых таблицы. Если это разные сущности в физическом мире - не надо их пихать в одно место. Иначе потом будет очень сложно все это дело сопровождать. А уж если тебе хочется использовать наследование - то пожалуста. Тот же PG позволяет создавать наследуемые таблицы.
Я своими постами хочу донести мысль - что не надо уходить в асбтракции данных с уровня БД на уровень инструмента разработки морды. Ты просто перестаёшь использовать все возможности БД (обычно "умные" фреймворки пытаются быть полностью не зависимыми от используемой БД) И в добавок, есть большая вероятность, что в итоге сформированный этим фреймворком запрос окажется очень не оптимальным с точки зрения БД Всё это ведёт к замедлению работы твоей системы. Чем мне и нравится концепция, которая работает в дельфи/лазаре по работе с данными - есть контроль.
SELECT DISTINCT trademarks.ID as trademarkID, trademarks.Number, IsJurholder, HolderID, trademarks.Address as PostAddress, Term, trademarks.GNumb, CASE trademarks.IsJurholder WHEN 1 THEN (SELECT Address FROM investpatents.jurlica WHERE ID=HolderID) WHEN 0 THEN (SELECT Address FROM investpatents.fizlica WHERE ID=HolderID) END AS Address, CASE trademarks.IsJurholder WHEN 1 THEN (SELECT Shortname FROM investpatents.jurlica WHERE ID=HolderID) WHEN 0 THEN (SELECT CONCAT(Familia,' ',LEFT(Name,1),'.',LEFT(Otchestvo,1),'.') FROM investpatents.fizlica WHERE ID=HolderID) END AS Shortname, CASE trademarks.IsJurholder WHEN 1 THEN (SELECT OGRN FROM investpatents.jurlica WHERE ID=HolderID) WHEN 0 THEN (SELECT ' ') END AS HolderOGRN, CASE trademarks.IsJurholder WHEN 1 THEN (SELECT INN FROM investpatents.jurlica WHERE ID=HolderID) WHEN 0 THEN (SELECT ' ') END AS HolderINN, CASE trademarks.IsJurholder WHEN 1 THEN (SELECT KPP FROM investpatents.jurlica WHERE ID=HolderID) WHEN 0 THEN (SELECT ' ') END AS HolderKPP, CASE trademarks.IsJurholder WHEN 1 THEN (SELECT Address FROM investpatents.jurlica WHERE ID=HolderID) WHEN 0 THEN (SELECT Address FROM investpatents.fizlica WHERE ID=HolderID) END AS HolderAddress, CASE trademarks.IsJurholder WHEN 1 THEN (SELECT CONCAT(Familia,' ',LEFT(Name,1),'.',LEFT(Otchestvo,1),'.') FROM investpatents.fizlica, investpatents.jurlica WHERE fizlica.ID=jurlica.RukID AND jurlica.ID=HolderID) WHEN 0 THEN (SELECT ' ') END AS RukFIO FROM investpatents.trademarks, investpatents.jurlica, investpatents.fizlica WHERE trademarks.ID IN (:IDlist);
mORMot пробовал? Это готовый ORM и REST API тоже там можно опубликовать автоматом насколько я понял. Не знаю умеет ли он генерить схему, но генерить схему по мне так плохая идея. Как и привязываться к конкретной СУБД.