Конференция "Базы" » Версия базы sql [D7, MSSQL]
 
  • yurikon (06.12.11 17:54) [0]
    Возможно ли в базе где-то прописать версию подобно ехе-файлу?
    Для чего это нужно - при обновлении версии программы, надо проверить соответствует ли версия базы данных версии программы. Если нет, то обновить структуру базы.

    С уважением.
  • sniknik © (06.12.11 18:01) [1]
    версия базы не зависит от структуры... что наводит на мысль, что это твоя версия... т.е. не версия базы, а версия твоей структуры. ну и пиши ее куда сам хочешь определи табличку и проверяй в ней значение.
  • Омлет © (06.12.11 18:14) [2]
    Надо хранить версию базы в самой базе. А так же весь список миграций.
  • yurikon (06.12.11 18:23) [3]
    Это понятно, думал может более красивое решение есть.

    Еще вопрос, опять же про обновление своей БД. Программа сама создает новую структуру БД, но в старой БД остается пара таблиц с данными, которые надо перенести в новую БД. Использовать SELECt INTO не могу, так как при этом не переносятся индексы и триггеры. Дополнительная проблема в том, что новая БД должна быть создана в том же месте и с тем же именем, что старая.

    Пока в голове такой сценарий - копирую данные во временные таблицы в базе temp. Удаляю старую БД. Создаю новую. И в самом делфи в цикле переношу рекорды. Насколько это правильно? Или есть более грамотное решение?

    С уважением.
  • Омлет © (06.12.11 19:07) [4]
    Существующие таблицы мигрируют через ALTER TABLE. Индексы обновляют.
  • Inovet © (06.12.11 20:02) [5]
    > [3] yurikon   (06.12.11 18:23)

    А почему в существующей не делеть обновление структуры? Прочитал текущую версию, накатил обновление до следующей см.
    > [4] Омлет ©   (06.12.11 19:07)
    > Существующие таблицы мигрируют через ALTER TABLE. Индексы обновляют.
  • Ega23 © (06.12.11 23:03) [6]

    > Использовать SELECt INTO не могу, так как при этом не переносятся
    > индексы и триггеры.


    Индексы и триггеры - самостоятельные объекты БД, если чё.
    Они также создаются, изменяются и удаляются.
  • Медвежонок Пятачок © (07.12.11 14:07) [7]
    версию хранить можно, но не нужно.
    потому что.

    нужно просто проверять наличие нужных объектов перед их использованием и создавать их если объектов нет.
  • Ega23 © (07.12.11 14:26) [8]

    > нужно просто проверять наличие нужных объектов перед их
    > использованием и создавать их если объектов нет.


    Больно монстрообразный скрипт получится.
  • Омлет © (07.12.11 14:45) [9]

    > Медвежонок Пятачок ©   (07.12.11 14:07) [7]
    > версию хранить можно, но не нужно.потому что.нужно просто
    > проверять наличие нужных объектов перед их использованием
    > и создавать их если объектов нет.

    Это даже для простейших случаев не годится.
  • Ega23 © (07.12.11 14:51) [10]

    > Это даже для простейших случаев не годится.


    Смотря для какой СУБД.
    Например, тот же MSSQL не строго к зависимостям между объектами базы относится.
    Соответственно, я совершенно спокойно могу сначала обновить структуру таблиц, а потом пересоздать существующие ХП.
  • Медвежонок Пятачок © (07.12.11 15:32) [11]
    Это даже для простейших случаев не годится.

    Что не годится?

    Ну записал ты версию в таблицу.
    Затем в базе кто-то што-то изменил. Например удалил добавленное тобой поле.
    Ты запускаешься, смотришь, версия кошерная, начинаешь селектить.
    И тут облом.
    Поля нет.
    Что ты делаешь?
    Снова его добавляешь.
  • Медвежонок Пятачок © (07.12.11 15:37) [12]
    > Это даже для простейших случаев не годится.
    Смотря для какой СУБД.


    У меня была мультисерверная программа.
    В том смысле, что работала с ораклом, mssql, access, mysql и фб.
    И использовался именно такой подход.
    Очередная новая версия знала, что для нее должны быть созданы такие то новые поля и такие-то новые таблицы.
    Плюс она помнила всю историю предыдущих апдейтов БД.

    В результате можно было взять самый свежую версию и подсунуть ей самую старую базу.
    И программу это нимало не пугало.
  • Омлет © (07.12.11 16:45) [13]

    > Медвежонок Пятачок ©
    > Очередная новая версия знала, что для нее должны быть созданы
    > такие то новые поля и такие-то новые таблицы.Плюс она помнила
    > всю историю предыдущих апдейтов БД.

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


    > Затем в базе кто-то што-то изменил. Например удалил добавленное
    > тобой поле.

    Не должен никто в базу лезть, кроме приложения. Иначе ССЗБ и база испорчена. И я не говорил, что проводить миграции надо без проверок.
  • Медвежонок Пятачок © (07.12.11 16:59) [14]
    И как ты определял, какие апдейты уже проведены, а какие нет,

    я не апдейты проверял, а существование объектов бд, которые появились в ней после того, как разошлась версия программы №1
  • sniknik © (07.12.11 17:13) [15]
    > я не апдейты проверял, а существование объектов бд
    у меня тоже самое сделано, но с добавкой проверки версии база/"структуры (какой смысл запускать кучу проверок, если версия уже последняя...) после апдейта версия подымается до максимальной а тот момент.

    если кто то влез и сам что то наисправлял... то ССЗБ.
    а так удобно, да, весь апдейт это новый exe подложить, и не заботится о запуске каких то скриптов, их порядка (есть, видел, зависят от номера и запускаются строго по порядку, т.е. сначала проблем себе навыдумывают, а после "обновляторы" пишут...)
  • Ega23 © (07.12.11 17:13) [16]

    > И как ты определял, какие апдейты уже проведены, а какие
    > нет, если версии у базы нет? С какого места начинать накатывать
    > правки таблиц?


    Что-то типа:


    if COLUMNPROPERTY(OBJECT_ID(N'[ISSCamera]'), 'SubAddr', 'precision') is NULL
    begin
    Print 'Добавить поле ISSCamera.SubAddr  - подадрес элемента модели';
    ALTER TABLE ISSCamera add SubAddr int NOT NULL default 0;
    end;
    go
    if COLUMNPROPERTY(OBJECT_ID(N'[ISSMonitor]'), 'SubAddr', 'precision') is NULL
    begin
    Print 'Добавить поле ISSMonitor.SubAddr  - подадрес элемента модели';
    ALTER TABLE ISSMonitor add SubAddr int NOT NULL default 0;
    end;
    go

    if exists (select 1
               from  sysobjects
              where  id = object_id('dbo.Abonents')
               and   type = 'U' and
               (COLUMNPROPERTY(OBJECT_ID(N'[Abonents]'), 'AbID', 'precision') is not NULL)
               )
      drop table dbo.Abonents
    go

    if exists (select 1
               from  sysobjects
              where  id = object_id('dbo.TaskAbPL')
               and   type = 'U')
      drop table dbo.TaskAbPL
    go

    if not exists (select 1
               from  sysobjects
              where  id = object_id('AbonentTyps')
               and   type = 'U')
    begin

     create table AbonentTyps (
      AbTypCod             int                            not null,
      AbTypNam             varchar(64)                    not null,
      AbTypLab             varchar(64)                    not null,
      AbTypOrd             int                            not null,
      AbTypMsk             tinyint                        not null,
      AbTypNot             varchar(255)                   not null,
      AbTypImg             image                          null,
      constraint PK_ABONENTTYPS primary key  (AbTypCod)
     );
     Print('Table created: AbonentTyps');
    end;
    go

  • Ega23 © (07.12.11 17:17) [17]

    > я не апдейты проверял, а существование объектов бд, которые
    > появились в ней после того, как разошлась версия программы
    > №1


    Это хорошо, если ты можешь перегенерить все триггеры, вьюхи и прочие ХП одним чохом, не заморачиваясь на dependences.
    Тот же FB такое не позволяет. Точнее, приходится адски геммороится и патч-скрипт разрастается до совсем неприличных размеров (если его очень аккуратно и правильно "вести").
    Посему - патч до версии такой-то, а если таблица или поле не существуют, а также кто-то туда своими шаловливыми ручками влез - ССЗБ, sniknik © + 1
  • sniknik © (07.12.11 17:28) [18]
    > Посему - патч до версии такой-то
    я не проверяю версию патча... проверяю версию структуры, и обновляю единым... который одинаково подымет с версии 1 или с предпоследней до последней...
    думаю Медвежонок про то и говорит.
    а вот с версиями патчей, в одной проге поддержке "наелся по самое не могу"...
  • Омлет © (07.12.11 17:28) [19]
    Убиться можно с такими проверками. Тем более в реляционной структуре, когда один апдейт каскадно удаляет таблицы, обновляет другие и патчит третьи, а второй создает таблицу, создает зависимости и заполняет данные на основе предыдущего изменения (а не неизвестного состояния). Многие апдейты решают только последовательные миграции (которые бывают очень сложными), т.к. в сложных системах не сводится все к добавлению несвязанных столбцов и новых табличек.
  • sniknik © (07.12.11 17:29) [20]
    > не заморачиваясь на dependences.
    ну почему же? все учитывается.
  • Омлет © (07.12.11 17:35) [21]
    В общем, я сторонник метода инкрементных изменений.
    Дабы не устраивать холивар, все читаем статью:
    http://habrahabr.ru/blogs/sql/121265/
  • Медвежонок Пятачок © (07.12.11 17:46) [22]
    статья дерьмо, автор комнатный теоретик.

    Моя ситуация:
    программа не коммерческая, а типа сдается в аренду другим юрлицам, которые работают с нами.

    что у них там происходит - контролировать не в моей власти и компетенции.
    И то, что кто-то там у них накосячил в данных - никого абсолютно не колышит.
    Особенно их и особенно моего шефа, которому они жалуются, если что-то не работает.

    В общем "работать должно всегда" и "ниипет-пишется раздельно".

    Вы им графоманские статьи с хабара в нос, а они вам : "а ниипет, должно работать"
  • Медвежонок Пятачок © (07.12.11 17:50) [23]
    К тому же:

    клиент получил версию №1.
    поработал немного и затих.
    прошло полгода.
    вышло 10 новых версий.
    клиент просыпается запускает версию №1 и обновляется до версии 11.

    итого:
    либо мне надо хранить все версии, а ему тупо их выкачивать и обновляться десять раз, либо его 11 версия не сможет взлететь с его версией базы №1.
  • sniknik © (07.12.11 18:04) [24]
    > клиент получил версию №1.
    > ...
    > клиент просыпается запускает версию №1 и обновляется до версии 11.
    аналогично.
  • sniknik © (07.12.11 18:07) [25]
    > автор комнатный теоретик.
    :), прочитал. там подход странный (хотя часто встречаемый именно в "поучениях") типа база главное, ее типа обслуживает, правит куча народу/программ, а программы типа неважны...
    но на деле чаще другое, главное программа, а что она за базу использует, и как, это ее проблемы. которые никого из клиентов в общем то не волнуют.
  • Омлет © (07.12.11 18:53) [26]

    > типа база главное, ее типа обслуживает, правит куча народу/программ,
    >  а программы типа неважны...

    Откуда такой вывод? Там четко написано: "Версия базы данных должна соответствовать версии приложения."
  • Ega23 © (07.12.11 19:22) [27]

    > ну почему же? все учитывается.

    create table xxx (id int);
    go

    create procedure s_xxx
     @id int
    as
    begin
     insert into xxx (id) valuse (@id);
    end;
    go;

    drop table xxx;
    go;



    Что выдаст MSSQL на drop?
  • sniknik © (07.12.11 19:52) [28]
    > Откуда такой вывод?
    общее впечатление. база всегда на первом месте.

    > Что выдаст MSSQL на drop?
    не в состоянии сначала удалить процедуру (тригер/констраинт/т.д.), если она есть?
    что по твоему значит "учитывается"?

    и к тому же, обычно не удаляется, обычно добавляется. выше версия, больше функционала в программе (иначе какой смысл изменениях?), больше используемых данных/"шире" структура в базе.
  • sniknik © (07.12.11 19:58) [29]
    > Что выдаст MSSQL на drop?
    и тест - говорит
    Выполнено применительно к -1 записям. (no recordset)
    конкретно тут нет зависимости
  • Ega23 © (07.12.11 21:08) [30]

    > конкретно тут нет зависимости


    Я об этом в [10] и говорил.


    > не в состоянии сначала удалить процедуру (тригер/констраинт/т.
    > д.), если она есть?


    В состоянии, от чего же. Но если туда логика работы с данными вынесена, то замучаешься удалять. Сначала одну, потом другую, потом пятнадцатую и восемнадцатую и только потом - третью. И таки мне эта концепция не нравится. Вот как в MSSQL - нравится.
  • sniknik © (07.12.11 23:24) [31]
    > И таки мне эта концепция не нравится. Вот как в MSSQL - нравится.
    ???, именно с mssql я и работаю. в основном. и применяю данную концепцию.

    > то замучаешься удалять.
    1
    > и к тому же, обычно не удаляется, обычно добавляется. выше версия, больше функционала в программе (иначе какой смысл изменениях?), больше используемых данных/"шире" структура в базе.
    это глюк в основах логики программы/структуре базы, если приходится удалять.
    2
    не вижу смысла "делить логику", и выносить часть в процедуры, опять "просвечивает" подход - типа "база главное и мощное, весь пентагон на ее обслуживание работает, а программа это, что-то незначительное сбоку".
    если можно, и легко сделать в программе, зачем процедуры? кто-то сказал что без них несерьезно? а реально они нужны?

    а ну да еще "резон", типа можно поменять процедуру без пере-компилирования программы ... нда, только часто вижу "бессмысленных монстров" в которых такое начинание вылилось в изменения, и стыковки по всей цепочке, всем кускам логики, вместо одного места в программе.
    т.к. инициатором обычно бывает клиент (ну кто еще может заказать пару колонок в отчете/форме, админ просматривающий базу, что ли, или юзер работающий с программой?)
  • Ega23 © (07.12.11 23:39) [32]

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


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


    > обычно не удаляется, обычно добавляется


    Это хорошо, если так. Но, тем не менее, шанс - есть. Глюк, не до конца продуманная логика, новые требования - это уже другой вопрос.


    >  "база главное и мощное, весь пентагон на ее обслуживание
    > работает, а программа это, что-то незначительное сбоку".


    Я этого не говорил, побойся Б-га.

    Если меняется одна-две процедуры, один-два триггера - то да, можно их отдельно дропнуть и создать заново. Если от них что-то зависит, то придётся сначала дропнуть то, что зависит, потом создавать заново. Если что-то зависит от того, от чего зависит первое, то... То уже проще дропнуть нафиг всё, накатить изменения на структуру таблиц, а потом пересоздать все хп и триггера заново.
  • sniknik © (07.12.11 23:53) [33]
    > Без хп или триггера (скорее - триггера) решать задачу замучаешься.
    пакет их 2х команд, апдейта и удаления завернутые в транзакцию. ну если там пара таблиц под изменения, то 3х команд... не вижу особых мучений.
  • Ega23 © (08.12.11 00:04) [34]

    > пакет их 2х команд, апдейта и удаления завернутые в транзакцию.


    А зачем, если можно одной командой сделать?
  • sniknik © (08.12.11 00:51) [35]
    > если можно одной командой сделать?
    самообман опасная вещь...  ну где же одна, если ты те же самые 2 команды вынесешь на сервер в процедуру, а третью, сам вызов процедуры будешь делать в программе. а считаеш только ее.
    вот это и есть то про, что говорил, ничего такого ради чего стоило бы создавать процедуру, но программа уже логическими частями "расползлась" в 2 места. разрыв логики.
    а после естественно возникнут проблемы, которые ты так хорошо описывал, типа передумал, надо переделать, само собой в апдейте, а уже в наличии 2 десятка процедур/тригерров и одна/одно от другой зависит.
  • Ega23 © (08.12.11 08:36) [36]

    > но программа уже логическими частями "расползлась" в 2 места.
    >  разрыв логики.


    Интересная точка зрения.
    Надо обдумать.
  • OW © (14.12.11 12:39) [37]

    > > но программа уже логическими частями "расползлась" в 2 места.  
    разрыв логики.
    >
    > Интересная точка зрения.
    > Надо обдумать.

    Да, если программа одна - две.

    И все-таки, нет, если БД одна, а программ много
    Должна быть хп. Что-то типа DeleteDocumentFolder (id_folder).
    И все должны с ней работать.
    Если все напишут в обертке транзакции удаление-апдейт, а потом БД поменяется, то все должны будут переписывать свои места.
    А если кто забудет что-то перписать - испортит БД.
    Вместо переписания одной процедуры.
  • sniknik © (14.12.11 13:06) [38]
    > И все-таки, нет, если БД одна, а программ много
    тогда идеологически база "главная", а программы это так, "приблуды". а в конце мы уже обсуждали другое, вариант когда программа "имеет базу", а не "база программу".
  • Ega23 © (14.12.11 14:07) [39]

    > тогда идеологически база "главная", а программы это так,
    >  "приблуды". а в конце мы уже обсуждали другое, вариант
    > когда программа "имеет базу", а не "база программу".


    Не так. Когда программа + база суть единое целое - тогда можно и ХП.
    Когда либо программа "может меняться" или их несколько, либо СУБД может меняться - тогда да, надо думать.
 
Конференция "Базы" » Версия базы sql [D7, MSSQL]
Есть новые Нет новых   [134431   +10][b:0][p:0.003]