6 июл. 2009 г.

Про дятлов...

Если бы строители возводили здания так, как программисты пишут программы, первый же дятел уничтожил бы цивилизацию.

Джеральд Вайнберг (Gerald Weinberg)

Время - великий учитель...

Le temps est un grand professeur, mais malheuresement il tue tous ses eleves.

Время - великий учитель, но, к сожалению, он убивает всех своих учеников.

Гектор Берлиоз, (Hector Berlioz)

3 июл. 2009 г.

Установка VSeWSS 1.3 на Windows 7

Процесс установки Visual Studio 2008 extensions for Windows SharePoint Services 3.0 хорошо описан здесь.

Нужно только добавить, что на Windows 7 установщик нужно обязательно запускать с правами администратора! Даже если Вы сами сидите с правами администратора.

Иначе, при deploymente проектов получается Internal Server Error (500). По крайней мере у меня было так.

И вообще, в Windows 7 Microsoft что-то сделала с системой безопасности. Это кончено к лучшему, но я пока не вник во все тонкости.

2 июн. 2009 г.

Мое резюме

Резюме на сайте еРабота.ру®-Новосибирск
Андрей Янович Гамарник, 22 года, холост, высшее образование, стаж работы 3 года.
http://nsk.erabota.ru/

8 мая 2009 г.

FILESTREAM SQL Server Management Studio

Сегодня возникла необходимость перенести сайт на другой сервер.И тут я обнаружил, что папка, где должны хранится объкты файлового потока (поле FileBody) пуста. Поначалу страшно испугался, но зайдя на сайт успокоиля ибо все работало.

А проблема вот в чем. Когда я разрабатывал базу данных, то написал примерно такой SQL:

CREATE TABLE dbo.SomeDatabase.File
(
        [Id] [uniqueidentifier] ROWGUIDCOL NOT NULL UNIQUE,
        [SerialNumber] INTEGER UNIQUE,
        [FileName] VARCHAR(512) NULL,
        [FileBody] VARBINARY(MAX) FILESTREAM NULL
)

GOSyhi-подсветка кода

А когда устанавливал базу на сервер, то воспользовался SQL Server Management Studio. Сгенерировал SQL-скрипт и выполнил его на сервере. А Management Studio сгенерировала такой код:

CREATE TABLE dbo.SomeDatabase.File
(
        [Id] [uniqueidentifier] ROWGUIDCOL NOT NULL UNIQUE,
        [SerialNumber] INTEGER UNIQUE,
        [FileName] VARCHAR(512) NULL,
        [FileBody] VARBINARY(MAX) NULL
)
GOSyhi-подсветка кода

Отличие в ключевом слове FILESTREAM. Видимо, не научили еще Management Studio его поддерживать. Использовал я Management Studio 2008 Express Edition (Версия 10.0.1600.22).

Тем не менее все прекрасно работало, только файлы сохранялись не на диске, а прямо в базе. В следующий раз буду внимательнее или буду восстанавливать базу из бэкапа.

P.S.: Перенес сайт на хостинг 1Gb.ru. А он не поддерживает технологию FILESTREAM. Так что может это и к лучшему :)

5 мая 2009 г.

LabVIEW Database Connectivity Toolset

Сразу предупреждаю – сейчас будет много критики. А критика это сложная штука. Потому что чувствуешь большую ответственность за сказанное, чем когда хвалишь что-то, и не хочешь оказаться в дураках, по причине недопонимания этого самого. Поэтому сразу сужу круг своей ответственности до LabVIEW Database Connectivity Toolset 1.0.1. Версия старая. В документации указан октябрь 2001.

Структура базы данных

Рассматривать будем простую таблицу, немного проще чем в моем дипломе.

CREATE TABLE IF NOT EXISTS `adcdata` (

`id`       INT(11)    NOT NULL AUTO_INCREMENT,
`channel`       INT(11)        NOT NULL,
`adcdata`       LONGBLOB       NULL DEFAULT NULL,
PRIMARY KEY (`Id`),
)Syhi-подсветка кода

LabVIEW Database Connectivity Toolset хорош

Начну, пожалуй, с хорошего. Это универсальная библиотека, работающая с любой базой данных, поддерживающей ODBC или OLE DB. Точно работает с Oracle, MS SQL Server, MySQL, Access.

Функции библиотеки (виртуальные приборы) очень похожи на функции классического ADO. Те же Connection-ы, те же RecordSet-ы. По RecordSet-у так же организуется проход курсором. Хочешь вызывай хранимые процедуры, хочешь делай параметризованные запросы, хочешь используй готовые функции (тогда и SQL писать не придется).

LabVIEW Database Connectivity Toolset плох

Основное предназначение LabVIEW – сбор и обработка данных. Данные – это чаще всего сигналы (аналоговые и цифровые). А сигнал это массив отсчетов (байт, слов). Логично подумать, что LabVIEW Database Connectivity Toolset должен уметь работать с двоичными данными. И он умеет! Но не совсем. В ходе своей работы я столкнулся с несколькими его ограничениями.

Во-первых, при записи сложных типов данных, например структур (кластеров) или массивов, Connectivity Toolset АВТОМАТИЧЕСКИ записывает перед данными их длину. 5 байт. Конечно, если считывать эти данные LabVIEW Database Connectivity, то все прекрасно, ибо он про эти 5 байт знает. А мне приходилось работать такими запросами:

INSERT INTO adcdata (channel, adcdata) 
VALUES (@channel, SUBSTRING(@adcdata FROM 5));Syhi-подсветка кода
Но эти самые 5 байт приходится обрубать и в запросах вида:

UPDATE adcdata
SET adcdata = CONCAT(adcdata, SUBSTRING(@adcdata FROM 5))
WHERE channel = @channel;Syhi-подсветка кода
Уж в этом случае добавление 5-ти байт в начало массива, точно является ошибкой разработчиков. К слову применение SUBSTRING к большим объемам данных пагубно сказывается на производительности.

Во-вторых, есть другая, еще более обидная проблем. Рассмотрим запрос:

SELECT adcdata FROM adcdata WHERE channel = @channelSyhi-подсветка кода

Напомню, что adcdata это двоичное поле типа LONGBLOB. А такой запрос, будучи выполнен средствами Database Connectivity Toolset, вернет только первые 65536 байт данных. Так уж устроен Database Connectivity Toolset. Самое интересное, то что никакими способами получить хотя бы один байт после первых 65536 у меня так и не получилось. Например, таким запросом:

SELECT BINARY SUBSTRING(adcdata, 65536, 2*65536)
FROM adcdata WHERE channel = @channelSyhi-подсветка кода
Двоичные данные при этом воспринимаются LabVIEW как символьная строка и кодируются странным образом. Никакие приведения данных средствами SQL не помогают.

А еще я так привык к ADO.NET, что мне очень не хватало класса типа DataAdapter и DataSet. Все-таки есть некоторая узкая специализация у LabVIEW и разрабатывать привычные нам приложения для работы с БД в нем трудновато. 

Например, стандартная задача: загрузка данных из БД в DataGrid, их правка и сохранение изменений обратно в БД. То что делается в Visual Studio за 15 минут в LabVIEW потребует значительных трудозатрат.

Резюме

  1. Итак, у LabVIEW Database Connectivity Toolset оказалось два серьезных ограничения:
    Он без спроса записывает длину двоичных данных перед самими двоичными данными
  2. Можно выбрать только первые 65536 точек. Но с оговоркой. Как я уже говорил, речь идет о версии 2001 года. В документации приводится информация об Oracle 7 и MS SQL 2000. И рассматриваются только типы данных VARBINARY и VARCHAR до 8000 байт. Никаких VARBINARY(MAX). Поэтому есть надежда, что второе ограничение устранено в новых версиях LabVIEW Database Connectivity Toolset.

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

Это функция выборки всех записей из таблицы с 18-ю полями. И не так страшно создание этой функции, как скажем ее рефакторинг :)

3 мая 2009 г.

Работа с двоичными полями в MySQL

Главная идея дипломного проекта была в том, чтобы хранить сигналы (отсчеты АЦП) в базе данных. 

Структура базы:

База данных была спроектирована задолго до меня и эксплуатируется уже несколько лет.
Нас интересует только одна таблица – adcdata, в которой и хранятся отсчеты АЦП. В поле adcdata хранится весь сигнал целиком.

Задача была записывать в это поле сигнал. Данные с АЦП поступаю порциями. При частоте 400кГц, поступает 768кБ/с. Эти данные нужно дописывать в гонец поля adcdata.

Конечно, хотелось писать в базу "налету", без всяких буферов на клиентской стороне. Но задача дозаписи данных в поле (запись в конец поля) для реляционных СУБД оказалась нетривиальной. Информации по таким решениям в интернете я не нашел. Вот несколько алгоритмов, придуманных мной.

Алгоритм №0

Идея: делаем SELECT уже записанных данных, на клиентской стороне приклеиваем к ним новую порцию данных и UPDATE-им все это в базу. Этот вариант пришел в голову первым и является совсем тупым решением. Я его даже не рассматривал.

Чтобы сделать UML диаграммы компактнее, я выбросил второстепенные параметры из SQL запросов.

Алгоритм №1

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

INSERT INTO adcdata (exp_id, channel, gain, adcdata)
VALUES (@exp_id, @channel, @gain, @adcdata)

UPDATE adcdata SET adcdata = CONCAT(adcdata, @adcdata)
WHERE exp_id = @exp_id AND channel = @channelSyhi-подсветка кода


Как оказалось, при выполнении конкатенации сервер сначала извлекает все содержимое поля adcdata в оперативную память, затем производит склейку и только потом записывает результат в поле.

Алгоритм №2

Второй алгоритм, придуманный мной, потребовал создания в базе данных дополнительной, временной таблицы. Идея заключалась в том, чтобы каждую новую порцию данных вставлять в очереднцю строку иаблицы. А по окончании процесса сбора данных, обработать содержимое этой таблицы хранимой процедурой и записать сигналы в исходную таблицу adcdata. Таким образом сохранялась совместимость с существующей структурой базы данных.

INSERT INTO temp (adcdata) VALUES (@adcdata)Syhi-подсветка кода
Работать это должно так:

Алгоритм №3

Как-то перечитывая документацию к MySQL я наткнулся на ключевое слово DELAYED. Его употребление вместе с INSERT дает возможность не дожидаться окончания выполнения запроса. Жаль, что для UPDATE его нельзя применить :) Я модифицировал алгоритм №2 так:

INSERT DELAYED INTO temp (adcdata) VALUES (@adcdata)Syhi-подсветка кода

Тест алгоритмов

Чтобы положить какие-то цифри в фундамент моих догадок относительно производительности этих алгоритмов, я написал небольшое тестовое приложение на C#. "Причем тут C#?", - спросите Вы. Все просто. Во-первых, мне были нужны относительные результаты. Во-вторых, на C# это было сделать просто. В-третьих, я даже не заморачивался насчет аппаратной конфигурации, так как мне нужены был качественные различия.

Результаты

Вот такие результаты я получил:

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

Алгоритм 2. Показал стабильное время вставки данных с небольшими случайными всплесками. 

Алгоритм 3. Как и ожидалось, это самый стабильный алгоритм.

К слову, об алгоритме 2 и 3. Тут нужно использовать хранимые процедуры, а это только MySQL 5.0 и выше.

P.S.: А как я все-таки реализовал запись сигналов в базу данных читайте в следующем посте про LabVIEW Database Connectivity Toolset.

Мой дипломный проект

Тема: Разработка автоматизированной измерительной системы на базе АЦП E-440 средствами LabVIEW.

Когда-то, давным-давно, была разработана система сбора, хранения и анализа экспериментальных данных: всяких аналоговых и цифровых сигналов. Работало все вокруг платы Advantech PCL-818L. Плата со стандартной начинкой: 12-битный АЦП (40кГц), ЦАП, цифровые входы и выходы. Основное отличие данной системы состояло в том, что экспериментальные данные хранились в реляционной базе данных, а не в куче двоичных фалов. Получилась такая распределенная лаборатория:

Сама система была разработана NI LabWindows – это такая специализированная среда разработки приложений для сбора данных.

Но захотели люди регистрировать быстроменяющиеся процессы. Купили модуль L-Card E-440: 14-битный АЦП (400кГц), ЦАП, цифровые входы и выходы.

И досталась эта тема мне в качестве выпускной работы бакалавра. Было предложено разработать аналогичную систему на базе модуля E-440 в LabVIEW. Я тогда как раз интересовался железом и LabVIEW, ну и я взялся за эту работу. В рамках бакалаврской работы я реализовал только базовые возможности системы. А сейчас уже довожу ее до ума. В том числе делаю дистрибутив.

Начну сначала. Как потом оказалось, LabVIEW в качестве инструмента разработки был выбран зря… Модуль E-440 хоть и умел с ним работать, но через одно место. А имя этому месту – Code Interface Node (CIN). CIN – это специальный блок для вызова пользовательских программ на языке Си. Эти программы нужно предварительно собирать компилятором командной строки – nmake. А потом загружать в CIN. При этом разработчик лишается всей радости отладки, так как CIN работает как черный ящик, а при загрузке программ в CIN, LabVIEW периодически без предупреждения завершается.

Значительным преимуществом LabVIEW, перед скажем C++ или Java, в этой ситуации была простая поддержка многопоточности. Многопоточность в LabVIEW реализуется, чуть ли не на подсознательном (интуитивном) уровне! Разработчик может даже не догадываться, что его программа распаралелена. Примерно так:

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

Компоненты. Что-что а разработанный в LabVIEW интерфейс пользователя заточен под сбор и обработку данных. Прежде всего это Chart-ы, Graph-ы, Array-контролы. Все что душе захочется.

Математические функции. Не буду приводить рекламных заявлений National Instruments по поводу поддержки огромного числа метематических функций средой LabVIEW, но их действительно очень много. Задачи вычисления спектральных характеристик, аппроксимации кривых и прочего анализа сигналов в LabVIEW решаются очень просто.
 
Ах, да! Базы данных! Для работы с базами данных предусмотрена специальная библиотека – LabVIEW Database Connectivity Toolset. Продается отдельно и стоит порядка 1000$. Впрочем, она достойна отдельной статьи и я расскажу о ней позднее.

Резюме. Основные требования к системе:
• Сбор аналоговых сигналов по 8-ми каналам на частоте 400кГц;
• Сбор данных и одновременная визуализация сигналов;
• Запись сигналов в базу данных (ее структура задана).
 

2 мая 2009 г.

Let's get it started

Решил наконец-то завести свой блог. Возникло сильное желание поделиться своими знаниями с людьми. А еще, по-моему, это удобный способ документировать свои знания.

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

Вобщем заканчиваю доделывать диплом и начну с цикла (пока думаю, что с цикла) статеек про LabVIEW, Database Connectivity Toolset и MySQL. А тема диплома: Разработка автоматизированной измерительной системеы на базе АЦП L-Card E-440 с применением LabVIEW.

Двоичная система

There are 10 types of people in the world: those who understand binary and those who don't.

Кто сказал - не знаю.