Глобалы MUMPS: Экстремальное программирование баз данных. Часть 3

Original author: Rob Tweed
  • Translation
  • Tutorial
Роб Твид (Rob Tweed)
Начало см. часть 1, часть 2.

Вторичные индексы

В реляционных базах данных вторичные индексы задаются как правило при определении таблиц, или после с помощью ALTER TABLE. Если индекс определён, то он автоматически создаётся, а потом поддерживается и пересчитывается базой данных при изменении данных.

В MUMPS индексы обслуживаются явно программистом, например, в функции обновления таблицы.

В следствии иерархической природы MUMPS-хранилища поле с первичным индексом используется как ключ.

Например, рассмотрим MUMPS-функцию по добавлению новой строки в ORDER:
setOrder(orderNo,data) ;
new rec,itemNo,ok
if orderNo="" Quit 0
; Вычислим общую стоимость заказа
set data("totalValue")=0
set itemNo=""
for set itemNo=$Order(^ITEM(orderNo,itemNo)) Quit:itemNo="" do
. set ok=$$getItem(orderNo,itemNo,.itemData)
. Set data("totalValue")=data("totalValue")+itemData("price")
set rec=data("custNo")_"~"_data("orderDate")_"~"_data("invoiceDate")
set rec=rec_"~"_data("totalValue")
set ^ORDER(orderNo)=rec
Quit 1


Обратите внимание на код для вычисления общей стоимости заказа. Мы проходим все записи из ITEM для определённого номера заказа orderNo и используем функцию $$getItem() для получения стоимости каждой вещи. Код функции $$getItem() таков:

getItem(orderNo,itemNo,itemData)
kill itemData
s itemData("price")=0
if orderNo="" Quit 0
if itemNo="" Quit 0
if ‘$data(^ITEM(orderNo,itemNo)) Quit 0
set itemData("price")=^ITEM(orderNo,itemNo)
Quit 1


Посмотрите на сроку, которая проверяет существование элемента в глобале для определённого номера заказа и номера вещи. Там используется MUMPS-функция $data и оператор отрицания одинарная кавычка `.

Давайте добавим индекс для быстрого доступа к покупкам каждого покупателя.

Для хранения индекса создадим новый глобал ^ORDERX1. Будем сохранять в глобале пару ключей: номер покупателя (custNo) и номер заказа (orderNo).

Чтобы индекс (custNo, orderNo) заработал расширим функцию setOrder следующим образом:

setOrder(orderNo,data) ;
new rec,itemNo,ok
if orderNo="" Quit 0
; Посчитаем стоимость заказа
set data("totalValue")=0
set itemNo=""
for set itemNo=$Order(^ITEM(orderNo,itemNo)) Quit:itemNo="" do
. set ok=$$getItem(orderNo,itemNo,.itemData)
. Set data("totalValue")=data("totalValue")+itemData("price")
set rec=data("custNo")_"~"_data("orderDate")_"~"_data("invoiceDate")
set rec=rec_"~"_data("totalValue")
set ^ORDER(orderNo)=rec
if data("custNo")`="" set ^ORDERX1(data("custNo"),orderNo)=""
Quit 1


Для создания заказа будем использовать эту функцию так:
set orderNo=21
kill data
set data("custNo")=101
set data("orderDate")="4/5/2003"
set data("invoiceDate")="4/7/2003"
set ok=$$setOrder(orderNo,.data)


Ссылочная целостность

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

Процесс поддержания ссылочной целостности отвечает за поддержание смысловой (в оригинале — semantic) целостности между связанными таблицами. В особенности, это связано с поддержанием взаимосвязей между таблицами на основе NATURAL JOIN (разные таблицы имеют столбцы которые хранят значения одного и того же типа, по которым и строится взаимосвязь между таблицами) или первичных/внешних ключей.

Например, когда номер клиента CUSTOMER.custNo меняется или удаляется, то в порядке поддержания смысловой целостности между таблицей клиентов и таблицей заказов должно быть произведено соотвествующее изменение поля ORDER.custNo.

Аналогично, когда номер заказа ORDER.orderNo меняется (или удаляется), то в порядке поддержания смысловой целостности между таблицей с заказами и таблицей вещей (из которых состоят заказы), соотвествующее изменение должно быть произведено с полем ITEM.orderNo.

В реляционных БД (RDBMS) правила обеспечения целостности задаются при создании таблиц с помощью первичных и внешних ключей. В MUMPS эти правила могут быть реализованы прямо внутри наших функций.

Помня о взаимосвязи между таблицами клиентов и их заказов, операция обновления CUSTOMER будет такой:

SQL

UPDATE CUSTOMER A
SET custNo = :newCustNo
WHERE A.custNo = :oldCustNo

В результате запроса будут обновлены соответствующие записи в таблице ORDER (по связи CUSTOMER.custNo=ORDER.custNo), если при определении структуры БД были правильно заданы соотвествующие внешние ключи.

MUMPS

updateCustomer(oldCustNo,newCustNo,newData) ;
new result,orderData,orderNo
if (oldCustNo="")!(newCustNo="") Quit 0
set orderNo=""
for set orderNo=$order(^ORDERX1(oldCustNo,orderNo)) Quit:orderNo="" do
. set result=$$getOrder(orderNo,.orderData)
. set orderData("custNo")=newCustNo
. set ok=$$setOrder(orderNo,.orderData)
set ok=$$setCustomer(newCustNo,.newData)
if newCustNo`=oldCustNo set ok=$$deleteCustomer(oldCustNo)
Quit 1


Заметьте, что этот код большей частью состоит из уже созданных нами функций для обслуживания таблиц CUSTOMER и ORDER. В MUMPS просто повторно использовать код.

Теперь создадим функцию $$getOrder:

getOrder(orderNo,orderData) ;
new record
if (orderNo="") Quit 0
set record=$g(^ORDER(orderNo))
set orderData("custNo")=$piece(record,"~",1)
set orderData("orderDate")=$piece(record,"~",2)
set orderData("invoiceDate")=$piece(record,"~",3)
set orderData("totalValue")=$piece(record,"~",4)
Quit 1

Нам также нужно расширить нашу изначальную простую функцию $$deleteCustomer(). Аналогичные соображения применим к операциям удаления строк из таблицы клиентов.

SQL-запрос и его эквивалент на M показаны ниже:

SQL

DELETE FROM CUSTOMER A
WHERE A.custNo = :custNo

В результате этого запроса соотвествующие записи о заказах будут удалены из таблицы ORDER (согласно связи CUSTOMER.custNo=ORDER.custNo и правилам целостности определённым при создании схемы БД). Правила целостности можно задать с помощью внешних ключей, например.

MUMPS

deleteCustomer(custNo) ;
new orderNo
if custNo="" Quit 0
set orderNo=""
for set orderNo=$order(^ORDERX1(custNo,orderNo)) Quit:orderNo="" do
. set result=$$deleteOrder(custNo,orderNo)
kill ^CUSTOMER(custNo)
Quit 1


Для кода выше нужна функция $$deleteOrder(). Вот она:

deleteOrder(custNo,orderNo) ;
kill ^ITEM(orderNo) ; Удалим все вещи входящие в заказ
kill ^ORDER(orderNo) ; Удалим заказ
kill ^ORDERX1(custNo,orderNo) ; Удалим связь между клиентом и номером заказа, используемую как вторичный индекс
Quit 1

Заметьте, что записи о всех вещах входящих в определённый заказ удаляются всего одной командой KILL по индексу с номером заказа. Это происходит потому, что между таблицами с клиентами и номерами их заказов есть каскадная связь (в терминах SQL).

Если при удалении клиента нужно сохранять информацию о его заказах, разрывая связь между клиентом и его заказами, то функция deleteCustomer примет такой вид:

deleteCustomer(custNo) ;
new orderNo,result,orderData
if custNo="" Quit 0
set orderNo=""
for set orderNo=$order(^ORDERX1(custNo,orderNo)) Quit:orderNo="" do
. set result=$$getOrder(orderNo,.orderData)
. set orderData("custNo")=""
. set result=$$setOrder(orderNo,.orderData)
kill ^CUSTOMER(custNo)
Quit 1

Аналогичная логика должна быть применена к данным хранящимся в таблице ITEM, когда изменяется или удаляется номер заказа ORDER.orderNo в таблице ORDER.

Триггеры

Триггеры — это простой способ вызова некого предопределённого кода при выполнении некоторых условий внутри БД. Обычно триггеры срабатывают при изменении некоторой информации в БД.

В реляционных БД триггеры определяются на уровне схемы БД. В MUMPS мы можем разместить любой триггерный код в функциях, которые обслуживают БД.

Возьмём, например, число заказов конкретного клиента CUSTOMER.totalOrders. Мы должны определить триггер для автоматического обновления этого поля при добавлении или удалении заказа из таблицы ORDER.

SQL

Данное SQL-выражение должно быть включено в код триггера для таблицы ORDER с целью обеспечения корректного значения в CUSTOMER.totalOrders:

SELECT COUNT(A.orderNo)
FROM A.ORDER
WHERE A.custNo = :custNo


Этот запрос будет срабатывать на операциях вставки и удаления строк в таблице ORDER (согласно связи CUSTOMER.custNo=ORDER.custNo)

MUMPS

Мы просто добавим следующий (триггерный) код в функцию вставки строки для таблицы ORDER:

setOrder(orderNo,data) ;
new rec,itemNo,ok
if orderNo="" Quit 0
; Подсчитаем общую стоимость вещей в заказе
set data("totalValue")=0
set itemNo=""
for set itemNo=$Order(^ITEM(orderNo,itemNo)) Quit:itemNo="" do
. set ok=$$getItem(orderNo,itemNo,.itemData)
. Set data("totalValue")=data("totalValue")+itemData("price")
set rec=data("custNo")_"~"_data("orderDate")_"~"_data("invoiceDate")
set rec=rec_"~"_data("totalValue")
set ^ORDER(orderNo)=rec
; Сохраним информацию для нашего вторичного индекса
if data("custNo")`="" set ^ORDERX1(data("custNo"),orderNo)=""
;
; Обновим значения поля CUSTOMER.totalOrders
new custData
Set ok=$$getCustomer(data("custNo"),.custData)
; При сохранении клиента будет автоматически пересчитано CUSTOMER.totalOrders. См. определение функции setCustomer в предыдущей части статьи
Set ok=$$setCustomer(data("CustNo"),.custData)
;
Quit 1

Эти же соображения применимы при удалении строк из таблицы ORDER. Подобная схема может использована для автоматического обновления стоимости заказа ORDER.totalValue при добавлении вещи в заказ.

SQL

Следующий SQL-код должен быть размещён внутри триггера для таблицы ITEM для вычисления нового значения стоимости заказа ORDER.Value:

SELECT SUM(A.price)
FROM A.ITEM
WHERE A.orderNo = :orderNo

Запрос будет срабатывать для всех операций вставки и удаления на таблице ITEM (согласно связи ORDER.orderNo=ITEM.orderNo).

MUMPS

Добавим следующий (триггерный) код в функцию вставки строк с таблицу ITEM:

setItem(orderNo,itemNo,data) ;
new ok
if (orderNo="")!(itemNo="") Quit 0
set ^ITEM(orderNo,itemNo)=data("price")
set^ORDERX1(custNo,orderNo)=""

; Обновим значение поля ORDER.totalValue
set ok=$$getOrder(orderNo,.orderData)
; При сохранении заказа поле ORDER.totalValue будет пересчитано
set ok=$$setOrder(orderNo,.orderData)
Quit 1

Те же соображения применимы к операциям по удалению строк из таблицы ITEM.
Следующим примером использования триггеров в нашей базе будет автоматическая генерация счёта-фактуры для клиента, как только дата его создания будет сохранена в поле ORDER.invoiceDate. Мы можем очень просто добавить эту функциональность в нашу процедуру обновления таблицы ORDER:

setOrder(orderNo,data) ;
new rec,itemNo,ok
if orderNo="" Quit 0
; Подсчитаем стоимость заказа
set data("totalValue")=0
set itemNo=""
for set itemNo=$Order(^ITEM(orderNo,itemNo)) Quit:itemNo="" do
. set ok=$$getItem(orderNo,itemNo,.itemData)
. Set data("totalValue")=data("totalValue")+itemData("price")
set rec=data("custNo")_"~"_data("orderDate")_"~"_data("invoiceDate")
set rec=rec_"~"_data("totalValue")
set ^ORDER(orderNo)=rec
if data("custNo")`="" set ^ORDERX1(data("custNo"),orderNo)=""
;
; Обновим поле CUSTOMER.totalOrders
new custData
Set ok=$$getCustomer(data("custNo"),.custData)
Set ok=$$setCustomer(data("CustNo"),.custData)
;
; Генерируем счёт-фактуру, если присутствует его дата
if Data("invoiceDate")`="" Set Result=$$invoiceOrder(orderNo)
;
Quit 1

Конечно, функция $$invoiceOrder() должна быть написана, чтобы произвести все необходимые действия по генерации счёта-фактуры.

Транзакции

Завершённое обновление БД часто состоит из многих обновлений некоторого числа таблиц. Все эти сопутствующие обновления должны быть гарантированно выполнены прежде чем основное обновление (или транзакцию) можно будет считать завершённым.

Как правило в реляционных БД транзакции включены по умолчанию. Другими словами изменения в БД не записываются до тех пор пока модифицирующий процесс не даст команду COMMIT, после чего всё изменения подтверждаются и начинается новая транзакция.

MUMPS очень похож в этом отношении, за исключением того, что транзакции должны быть явно включёны. Программа должна обязательно выполнить команду запуска транзакции TSTART, а не только подтвердить её завершение TCOMMIT.

SQL

Подтверждаем текущую транзакцию и (неявно) запускаем новую:

COMMIT

MUMPS

Начать новую транзакцию:

TSTART

Подтвердить транзакцию:

TCOMMIT

Если управление транзакциями явно не включено в MUMPS-системе, то все обновления будут немедленно применены к текущему хранилищу. Иными словами любая SET или KILL команда на глобале или его элементе может быть рассмотрена как завершённая транзакция.

Выводы

Есть много ключевых преимуществ использования MUMPS по сравнению с традиционными реляционными БД.

  • Повторное использование кода и простота сопровождения. При аккуратном программировании можно достичь экстремального высокого уровня повторного использования кода. Вышеприведённые примеры показывают как можно инкапсулировать все действия с БД в рамках функций set, get и delete для каждой таблицы. Пишите эти функции один раз, а потом используйте их сколько хотите.
  • Переносимость. Определения структур данных содержатся внутри функций, которые работают с ними. Нет никакого различия между определением данных и их реализацией.
  • Гибкость. Код, обновляющий данные, может быть изменён на срабатывание по любому действию или событию внутри системы.
  • Производительность и оптимизация. Опытные MUMPS-аналитики увидят возможности для оптимизации функций использованных нами для работы с БД. Это возможно потому, что определение данных и реализация операций над ними содержатся вместе внутри конкретных функций. Аналитик использующий SQL на имеет точного контроля над тем, каким образом обрабатываются триггеры, действия по обеспечению ссылочной целостности и транзакции.
  • Преимущества использования SQL для работы или извлечения данных (для этого можно использовать специальные утилиты) не потеряны, потому что слой определения данных может быть прозрачно наложен на существующие MUMPS-таблицы (глобалы). Это можно сделать в последствии. Например, Caché SQL и сторонняя утилита KB_SQL реализуют полноценное SQL-окружение поверх глобалов MUMPS.
AdBlock has stolen the banner, but banners are not teeth — they will be back

More
Ads

Comments 46

    0
    А почему примеры не используют lock? Если другой пользователь одновременно изменит состав заказа? Ведь транзакции вы тоже там не применили.
    Понятно, что вопрос к Робу, как автору, но может вы поясните.
      0
      Я думаю Роб не хотел перегружать вводную обучающую статью. Её перевод итак занял 3 огромных части.

      Безусловно, в реальной серьёзной системе будут использоваться блокировки по конкретным заказам с вложенными транзакциями.
        0
        Собственно multik обещал про транзакции и блокировки в своей серии статей рассказать. Мне кажется, будет отличное дополнение.
      0
      Рекомендую из оригинала заменять такие кавычки ”” на обычные "" — это никак не влияет на синтаксис но делает более удобной читабельность и подсветку.
        0
        то есть использовать обычные двойные кавычки везде (в комментарии разницы между ними не видно)
          0
          и использовать обычную одинарную кавычку
          0
          А какие сейчас перспективы использования MUMPS? Ведь все больше систем появляется — где например все данные лежат в наитупейших SQL таблицах типа ID, VALUE, а VALUE представляет собой упакованную в XML сущность произвольной структуры и наполнения.
          В таких системах все соединения, поиски, маш-апы делаются на сервере приложений — который строго говоря можно сделать как угодно умным, с параллелизмом, с многонодовостью и даже с тонким оптимизатором (например хранить индексы не в виде B-tree, а T-tree — что гораздо интереснее в случае хранения данных в оперативной памяти) и денормализатором данных

          Скорость получается фееричная — даже на весьма средненькой технике мы получали 15-20 тыс. бизнес-транзакций в секунду на тысячах пользователей…
            –1
            Кам мне кажется, самое главное — то, что MUMPS позволяет делать перечисленно вами не на 2 уровне трёхзвенки ( сервере приложений) а на 1 уровне двухзвенки (СУБД). И делать это нормально. И, если верить статьям, с ещё большей скоростью.
              0
              Ну если это сервер БД такой умный — то думаю все равно влетим в ограничение «железной» архитектуры. Тот же IRQ delay — и скажем в Intel архитектуре на 8000 пользователях хваленый Oracle уже будет помирать. Выход — уйти от одного процессорного ядра — в несколько нод — не сотен, а тысяч легких связанных в сеть вычислителей (ну типа MapReduce) схем
                0
                p.s. Бизнес транзакция — это законченная, имеющая физический смысл — операция. Например — проведение платежа по счету клиента — которая «цепляет» проверку прав операциониста, проверку остатка, запись в документы дня, расчет комиссии, проводки по корреспондирующим счетам и полную запись в аудит операций и безопасности…
                  0
                  В общем — да.
                    0
                    Кто мешает использовать Caché на тысячах серверах в качестве сервера приложений, объединив их с помощью ECP?
                    Здесь даже была статья на эту тему.
                      0
                      да — вобщем ничего. Просто каждому решению — свое время. Мы например активно занимаемся интеграционными ИС — когда архитектура составляется из множеств компонент различных производителей по принципу «best of breed». И сквозными бизнес-процессами — которые все стягивают. Понятно — что это все делается на серверах приложений — где роль СУБД уже не главная. Поэтому реализовать непростой data transformation нам проще на том же языке, что и все остальное (J2EE). Т.е. критерии чисто экономические — наличие рынка специалистов и унификация инструментария.
                        0
                        Для интеграционных ИС существует отдельный продукт Ensemble, но который базируется опять же на Caché.

                        Основной мой посыл был в том, что покупая один продукт, вы в рамках предоставляемых им технологий получаете сразу и СУБД, и сервер приложений, и real-time BI, и технологию/фреймворк для разработки веб-приложений.

                        В подавляющем большинстве случаев предоставляемых Caché возможностей мне хватает, а если нет, то: #comment_5894797
                          0
                          А смысл — идя покупать в магазин шнурки, брать впридачу еще и костюм? ;-) Часто мои заказчики работают в модели «best of breed» — т.е. выбирают для решения задачи самые лучшие компоненты из нужных сфер. Вполне понятно, что это будут разные вендоры, поэтому хочется гибкости, компонентности и открытости
                            0
                            Но ведь после того, как заказчики выбрали «best of breed» Вы все это объединяете интеграционной шиной? И какую шину используете? Почему например не выбрать Ensemble в качестве шины — ведь по сравнению со стеками технологий от IBM и Microsoft, InterSystems Ensemble — действительно «все в одном», что ИМХО упрощает решение, а также удешевляет и упрощает эксплуатацию.
                –1
                К слову говоря подобная структура на MUMPS будет работать быстрее, чем на SQL. Смотря что, конечно считать транзакцией. Они могут очень отличаться по сложности. Я когда делал тесты с GT.M (бесплатный MUMPS) достигал результатов в 660 000 insert-ов в секунду (база данных на диске, а не в памяти) на 4х3.6GHz Phenom, 8gb, RAID5. Вставлял для теста 10 миллионов записей.

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

                Да и XML не самый быстрый способ сериализации структур.
                  0
                  Так на 3-tier архитектуре (вернее как подмножество N-tier) можно делать чертовски прикольные вещи — например read ahead чтение с построением декартова произведения любых нужных таблиц с их векторным умножением/пересечением и пр. И это все асинхронно — т.е. клиент даже не догадается как его данные в кубы заворачиваются, меняя физическое представление — совершенно не связанное с их хранением на диске.

                  А по поводу insert — так по-моему batch insert (bcp) на MS SQL и так дает такую скорость, особенно если есть мощный write cache — с размером более объема вставляемых данных
                    +1
                    С миллионов (энерго/газо/водо/др.)-счётчиков приходят по сети данные (сокеты/веб-сервисы/http/etc.), которые нужно быстро вставить в БД, предварительно ещё обработав перед и после вставки. И всё это в непрерывном режиме.

                    Как в этом случае поможет программа bcp?

                    Подробнее о ETL на лету можно прочитать в этой cтатье.

                    Поскольку СУБД Caché может выступать и в роли сервера приложений, то осуществление этого в рамках её технологий вполне возможно.
                      0
                      Прошу прощения — мы как то перешли от философии MUMPS к продуктовой линейке Caché. Лучше это обсудить в отдельном топике в сравнении с аналогичными технологиями. Просто думаю идет конвергенция решений и технологий на фоне жестокой конкуренции — 99,9% инфраструктурных ИТ решений — как и лекарства имеют аналоги, (дженерики). InterSystems Corp была основана практически в том же году что и Oracle — но обороты ( $450 млн. против $37 млрд) даже меньше чем у Sybase — и отстраивание одного продукта от другого начинает носить уже малоразличимый, скорее маркетинговый характер. Мы же не будем холиварить? Caché — отличный _нишевый_ продукт.

                      p.s. Мы используем для интеграции данных в реальном времени и постоянную доступность данных для критически важных систем решение Oracle GoldenGate. Оно имеет задержку не сотни, как в обычном ETL- а единицы миллисекунд.
                        +1
                        Я правильно понимаю, что в таком случае помимо Oracle Database Enterprise Edition и, возможно, какого-то из Application Server, необходимо будет дополнительно покупать ещё Oracle GoldenGate, GoldenGate for Non Oracle Database и GoldenGate Application Adapters?
                          0
                          Да. А разве где-то иначе? Прайс-лист глобальных компаний уже давно представляет собой томик «Война и мир». Я бы тоже предпочел видеть все одной суммой и unlimited, но вероятно их «эффективные менеджеры» привязали каждую позицию к доходам отдельного подразделения — чтобы не было перекрестного финансирования и можно было развивать каждое направление, не делясь прибылью с другими.
                          0
                          Ничего не мешает на MUMPS писать сервер приложений, и не зацикливаясь на Каше. У GT.M всего одно неудобство(может уже устранили) по передаче сокетов в дочерние процессы. Просто в Каше вокруг голого MUMPS уже накрутили то, что может облегчить труд программистов.
                            0
                            У GT.M всего одно неудобство(может уже устранили)
                            GT.M уже официально поддерживает Windows?
                              0
                              Насколько я знаю Windows существует, но она с закрытым кодом и платная.
                                0
                                Я знаю, что какая-то версия GT.M под Windows вообще существует.
                                Вопрос был про официальную поддержку платформы Windows самим производителем.
                                  +1
                                  И поддержка есть. И тоже платная.
                                    0
                                    Можно pruf аналогичный этому?

                                    Из википедии:
                                    The code base for GT.M on GNU/Linux on IA-32 (x86) includes changes needed to run on Cygwin on Microsoft Windows but this is not yet considered a supported platform.

                                    И ещё.
                                      0
                                      Это вообще не пруфы. Доказательства нужно искать на сайте производителя, а не среди трёпа на стековерфлов.

                                      Как бесплатное решение (FOSS — Free and open-source software) действительно GT.M есть только под Unix-подобныи ОС.

                                      Тут указан емейл, где ты можешь заказать версию под другие платформы, чем Unix-подобные:
                                      tinco.pair.com/bhaskar/gtm/doc/books/ao/UNIX_manual/ch02s01.html

                                      А тут указан емейл по которому ты можешь заказать платную поддержку
                                      www.fisglobal.com/products-technologyplatforms-gtm-faq
                                        0
                                        Я попросил ссылку, где чётко указано, что уже есть поддержка GT.M под Windows, а не «сейчас нет, но вы нас попросите и мы вам сделаем всё что угодно за ваши деньги».

                                        Если такой дистрибутив есть, то какой смысл его скрывать или хотя бы указать в документации информацию о том, что он существует?

                                        С таким же успехом я могу заказать СУБД Caché под Raspberry Pi или Android, которых сейчас тоже нет.

                                        PS: упоминание платности (special for Windows) как для заказа дистрибутива, так и для техподдержки вообще снимает всякие дополнительные вопросы.
                                          0
                                          Там не указано, что нет версии под Windows, так что не нужно фантазировать. Поскольку данный вопрос интересен тебе, а не мне, то напиши и спроси.
                                            0
                                            Не имею привычки что-то домысливать за документацию:
                                            GT.M V6.0-002 Release Notes: Platforms

                                            «А что сверх этого, то от лукавого» (Матфей 5,37)
                                              0
                                              Я у же говорил:

                                              Как бесплатное решение (FOSS — Free and open-source software) действительно GT.M есть только под Unix-подобныи ОС.


                                              Мне не нужно подтверждение моих слов ссылкой из документации к бесплатной версии GT.M ))
                                                0
                                                Разработчикам тяжело было сделать два раздела:
                                                1. Платформы для бесплатной версии
                                                2. Платформы для платных версий?

                                                Я пока так и не увидел подтверждения на основе открытых официальных источников ваших слов:
                                                Насколько я знаю Windows существует, но она с закрытым кодом и платная.

                                                Кулуарная информация меня не интересует.

                                                А специально куда-то писать, чтобы узнать эту информацию, как вы мне советуете, я не собираюсь. И не только поэтому.
                                0
                                Это кому нибудь может мешать?
                                  0
                                  Вы имеете в виду мешать начать использовать и хотя бы попробовать для не Linux-разработчика?
                                  Да пожалуй, что нет, совсем не мешает.
                                    0
                                    Скорее я имел в виду, что не стоит придумывать искуственные недостатки. Например Каше не работает на Raspberry Pi :).
                                      0
                                      не стоит придумывать искуственные недостатки

                                      Как вам будет угодно.
                          0
                          Кстати, я повторил тест на таком объёме, который гарантированно не влезет в write-cache, поскольку он у меня имеется.
                          Взял объём данных, который в 10 раз больше моего кеша. Винты шуршали как бешеные.

                          Получилось 293 544 инсертов в секунду.

                          Причём тест проводился в виртуальной машине (Vmware Player), что значит на реальном железе будет ещё быстрее.
                            +1
                            Вот видите — мы уже холиварим ;-) Ну не актуален для меня тест insert, поскольку есть такие системы — которые нормально включаются в режим pass thru — напрямую прокачивая данные от датчиков сразу на HDD. И даже CPU не задействуют — потому как в DMA режиме живут.
                            Понятно что самая быстрая скорость будет на записи в текстовые файлы фиксированного блока данных, кратного пакету DMA/Ethernet/IP и пр. Так работает кстати процессинг VISA — там нет SQL движка.

                            По поводу виртуалки — «падеж скорости» у меня был не более 15-20% относительно натуральной машины. В основном это опять же зависит от дефрагментации виртуального/реального диска и их отображения.

                            Подытоживая — в нишевых продуктах можно добиться сколь угодно большого перфоманса. Особенно если они анизотропные — т.е. системы только пишут данные или только читают. Самый геморрой — это когда идет мешанина читающего и пишущего кода — и вот тут поле битвы современных СУБД. Есть даже такие — которые еще на этапе компиляции отделяют один код от другого и запускают с соответствующей оптимизацией на разных нодах в асинхронном режиме с семафорами. Мне такой подход сильно нравится.
                              +1
                              Я вообще не холиварю. И ваш коммент мне нравится и я с ним согласен. Однако, хочу заметить, что в моём тесте попутно со вставкой производилась ещё и индексация по главному глючу.

                              Ради интереса провёл ещё тест на случайный селект с использованием главного ключа:

                              833 селекта в секунду. Естественно на таких объёмах данных, где кеширование не работает.

                              Всё упирается в iops hdd.

                              И ради интереса провёл тесты на селект на таком объёме, который может влезть в кеш с использованием read ahead:

                              1 066 666 селектов в секунду.
                              0
                              Поправка: часто бывает так, что в виртуалках диски работают быстрее, чем реальное железо из-за writeback'а на хосте, игнорирующего мольбы о fsync'е из гостя.

                      Only users with full accounts can post comments. Log in, please.