Violet Tape некоторые мысли о разработке на платформе .Net

6Фев/121

Целые vs GUID vs Естественные и Суррогатные ключи

 

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

Естественный vs Суррогатный ключи

Джо Целко (Joe Celko) утверждает что мы должны использовать естественные ключи, созданные из атрибутов записи, а не заниматься присвоением произвольных значений записям в таблицах. Я согласен с ним. Но! В то же время мы должны стараться хранить ключи легкими/маленькими, вместо того, чтобы создавать массивные составные ключи, чьи значения в свою очередь должны будут храниться в других таблицах для возможности соединения таблиц, поддержания их целостности. Как я выбираю какой способ использовать? Легко, я использую оба.

Сейчас я поясню. В базе данных первичный ключ является естественным, однако я создаю суррогатный ключ, который может быть использован для соединения таблиц. В этом случае получаем хорошую производительность как для объединения таблиц, так и для выборок. Однако я усиливаю естественный ключ суррогатным для того, чтобы два значения не вставились одновременно.

Метки записи: , , Читать полностью
16Ноя/110

Dapper – micro-ORM — II

Продвинутые возможности

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

Пакетная вставка данных как пример использования списка параметров

С помощью Dapper можно осуществлять пакетную вставку данных передав  список данных. Т.е. у нас есть список людей для внесения в базу данных, и с помощью единственной команды можно это провернуть. Лучше сразу на примере показать:

    public void ExecuteNonSelectBulkCommand() {
        con.Open();

        var list = new List();
        for (var i = 1; i < 5; i++) {
            list.Add(new Person {
                                    PersonId = Guid.NewGuid(),
                                    Birth = new DateTime(1980, i, i),
                                    Name = "Pers " + i,
                                });
        }

        con.Execute("INSERT INTO Person (PersonId, Name, Birth) VALUES(@PersonId, @Name, @Birth)"
                    , list);

        var persons = con.Query("Select * from Person");
        foreach (var p in persons)
            Console.WriteLine("{0} {1} {2}", p.Name, p.Birth, p.Resident);

        con.Close();
    }

Создаем несколько экземпляров класса Person, и передаем список в качестве параметра в команду Execute. Потом можно визуально проверить результат.

В качестве параметра для пакетной обработки может выступать любая коллекция, которая реализует интерфейс IEnumerable<T>.

Упс!

Ничего же не менялось в коде, и все переменные указаны верно, в чем же дело?

Метки записи: , Читать полностью
14Ноя/110

Dapper – micro-ORM — I

Недавно я рассказывал про легковесную ORM BLToolkit, и при поиске и изучении материала неизбежно наталкивался на сравнение BLT с другими разработками в области мапирования данных на бизнес-объекты. Одним из самых привлекательных вариантов по скорости, а так же по вниманию общественности, оказался Dapper.

Dapper – это даже не легковесная, а микро-ORM система для чтения (в основном) информации из реляционных баз данных. Данная микро-ORM система является разработкой Сэма Сафрона (Sam Saffron) для Stack Overflow, где она работает в связке с Linq2Sql. Для такого большого и посещаемого ресурса как Stack Overflow очень важно быстро получать информацию из базы данных, так как большинство пользователей просматривает ответы, использует их в своей работе, и сравнительно редко пишет. Для записи информации, что требуется значительно реже, до сих пор самым удобным и быстрым остается Linq2Sql.

О системе

Dapper – это по сути один файл с исходным кодом, который надо включить в свой проект. Dapper работает в некотором роде классом помощником, расширяя стандартный интерфейс IDbConnection с помощью extended методов. Т.е. данному фреймворку абсолютно без разницы, с какой базой вы работаете, если соединение с ней построено на указанном интерфейсе.

Метки записи: , Читать полностью
26Сен/110

Eloquera V

краткое описание / немного истории / установка / режимы работы базы: service, inmemory, desktop / восстановление базы
конфигурация / программная конфигурация / простейшие операции CRUD / insert / update / refreshMode / delete
построение запросов / joins / параметры / массивы / шаблонные контейнеры / order by / доступные функции / almos
хранимые процедуры
родные и динамические объекты / работа с массивами / контейнеры / фильтрация типов, свойств и полей / backup and restore / эволюция типов / fulltext search / индексация / под капотом

«Родные» и динамические объекты

Под родными объектами в данном случае подразумеваются любые типы принадлежащие CLR или созданные вами. Eloquera может на лету (в runtime) конвертировать динамические объекты в «родные» и обратно.

Внимание!

Для использования этого функционала должно быть открыто соединение к базе.

Основные методы для конвертации:

  • ToNative<ConcretType>()
  • FromNative(variable)

Пример для уже открытой базы по созданию динамического объекта:

 Book book = new Book { DbID = 12345,  Title = "Title Mitle" }
 Dynamic dynObj = new Dynamic(book);
 db.Store(dynObj);
 Book newBook = dynObj.ToNative();

При обновлении данных применяются следующие схемы работы:

  • Обновление через родной тип

0    Динамический тип переводим в «родной» тип

0    Изменяем «родной» тип

0    Обновляем (синхронизируем) динамический тип с помощью FromNative

  • Обновление через динамический тип

0    Существует переменная конкретного типа с данными динамического

0    Изменяем динамический тип

0    Обновляем (синхронизируем) «родной» тип с помощью ToNative<T>(variable)

23Сен/110

Eloquera IV

краткое описание / немного истории / установка / режимы работы базы: service, inmemory, desktop / восстановление базы
конфигурация / программная конфигурация / простейшие операции CRUD / insert / update / refreshMode / delete
построение запросов / joins / параметры / массивы / шаблонные контейнеры / order by / доступные функции / almos
хранимые процедуры

Хранимые процедуры

Начиная с версии 4.0 Eloquera поддерживает хранимые процедуры. Я думаю, не стоит расписывать все прелести и возможности хранимых процедур. Те, кто работают с базами и так их знают. Хочу только заметить, что результат выполнения хранимой процедуры остается, связан с контекстом базы, а значит, полученные данные можно изменять и обновлять объекты в базе.

Хранимые процедуры могут рассматриваться как методы расширения к основной базе. Они пишутся с использованием C#, за что благодарность создателям, за то, что они не выдумали какой-либо свой интерпретируемый диалект для этого дела. Получается, что можно использовать все возможность .Net при написании процедур.

Итак, хватит слов, лучше показать, как создаются хранимые процедуры на деле.

Первым делом надо объявить интерфейс  с желаемыми процедурами. Данный интерфейс должен находиться на стороне клиента и сервера.

public interface ICityStatisticSP{
    CityCars GetCityCars(string cityName);
}

Затем создаем класс, который нужен будет только на стороне сервера. При этом библиотеку с реализацией процедуры надо поместить в папку Lib в директории базы, либо настроить путь до библиотек с хранимыми процедурами с помощью параметра StoredProceduresPath.

public class CityStatisticSP: StoredProcedure, ICityStatisticSP {
     public CityCars GetCityCars(string cityName)  {
         Parameters parms = db.CreateParameters();
         parms["city"] = cityName;

         var cars =   db.ExecuteQuery("SELECT Car FROM Car JOIN Seller ON Car.SellerID = Seller.ID WHERE Seller.City = @city", parms)
             .OfType()
             .ToList();

           …

     }
 }

Добавление новых процедур не требует перезапуска сервиса базы данных.

21Сен/110

Eloquera III

краткое описание / немного истории / установка / режимы работы базы: service, inmemory, desktop / восстановление базы
конфигурация / программная конфигурация / простейшие операции CRUD / insert / update / refreshMode / delete
построение запросов / joins / параметры / массивы / шаблонные контейнеры / order by / доступные функции / almos

Построение запросов

Eloquera позволяет писать запросы к базе данных на привычном многим SQL, причем с приятными дополнениями, которые я не встречал в MS SQL. Запросы можно писать в отношении полей и свойств класса, к дочерним объектам, коллекциям и массивам объектов. Все вместе это дает очень мощную платформу для анализа данных.

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

  • ExecuteQuery(string query)
  • ExecuteScalar(string query)

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

Общий вид и порядок служебных слов в запросе тот же, что и в «обычном» SQL . Если делается запрос к одной сущности, то слово from можно опустить. Например:

var result = eloquera.ExecuteScalar("Select ClassId where Text = 'XXX'");

Eloquera поддерживает операторы TOP, SKIP, Order by (подробно будет чуть позже).

var result = eloquera.ExecuteQuery("Select Top 5 ClassId");

var result = eloquera.ExecuteQuery("Select Skip 3 ClassId");

Запросы можно строить не только для собственных полей класса, но и обращаться к составным полям, массивам. Сложный объект может содержать другие объекты или массивы, например:

public class BasicUser {
 	public Location HomeLocation;
     public Location CurrentLocation;
     public string Name;
     public DateTime BirthDate;
     public string Interests;
     public BasicUser[] Friends;
     public WorkPlace UserWorkPlace;
     public School UserSchool;
     public string[] Emails;
}
19Сен/110

Eloquera II

краткое описание / немного истории / установка / режимы работы базы: service, inmemory, desktop / восстановление базы
конфигурация / программная конфигурация / простейшие операции CRUD / insert / update / refreshMode / delete

Конфигурация

Файл конфигурации в поставке для автономной работы (Desktop mode) по умолчанию выглядит следующим образом:

<?xml version="1.0"?>
<Eloquera xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Cache IndexCacheSize="1000"
	   WriteThru="false"
	   IndexCleanerPeriod="100"
	   IndexCleanerBatchSize="100"
	   CleanerPeriod="100"
	   CleanerBatchSize="2000"
	   CommitSequenceMaxLength="2000"
	   ShallowReadThreshold="1000"
	   ShallowReadAhead="1000"
	   ReadAhead="20"
	   SaturationThreshold="10000"
	   MemoryFootPrint="1000"/>
<MemoryManager Mode="1" />
<Server ServerPort="43962"
        Trace="true"
        InMemoryAllowed="true"
        Secure="false"
        AllowUsers=""
        AllowGroups="Everyone" />
<SmartRuntime Smart="true" />
<UserLogin Enabled="false"
PasswordHash="l+on1aCwDrcZ5bGlv+fyyIlYkbuFIOxZFlFwIGKlms0CCwoGn9TZvM0E3Uksjwx64+/yv8nsaUajWLz1kyKG7A==" />
</Eloquera>

 

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

Внимание!

С версии 4.0 можно полностью игнорировать файл настройки и задание директории для хранения баз данных. Eloquera самостоятельно все определит и настроит.

16Сен/110

Eloquera I

краткое описание / немного истории / установка / режимы работы базы: service, inmemory, desktop / восстановление базы

Краткое описание базы

База данных Eloquera с самого начала была написана для хранения объектов  на основе .Net Framework, что сделало возможным попытаться вобрать в себя все лучшее от объектных и реляционных баз данных одновременно, преодолев многие их различия. Теоретически Eloquera может работать с любыми объектами из семейства .Net Framework, однако на практике работа проверялась пока только с C#. Главная ориентированность разработчиков на enterprise сегмент, а не на embedded решения.

Отличительные особенности Eloquera весьма внушительны и постоянно пополняются, вот их примерный список:

  • Сохраняет C# объекты (любые объекты любого языка на .Net платформе) без необходимости реализации специальных интерфейсов и адаптеров.
  • Сохраняет Dynamic объекты с любыми полями\свойствами и может сопоставить их объектам любого типа.
  • Язык запросов максимально приближен к SQL, при этом не требуется наличие какой либо реляционной SQL базы.
  • Поддержка LINQ.
  • Возвращает объекты в том виде, в котором они были сохранены (включая перечислимые типы)
  • Поддержка параметров в виде списков и массивов. В свою очередь массивы могут быть многомерными – синтаксис запросов остается неизменным.
  • Поддержка функций и выражений в запросах и конструкции ORDER BY.
  • Стандартный и расширенный ORDER BY.
  • Регулярные выражения в запросах.
  • Индексация и оптимизация запросов.
  • Пакетная вставка и обновление данных.
  • Поддержка шаблонных объектов.
  • Восстановление Read-only полей и свойств.
  • Учет классов наследников в запросах. Select ParentClass вернет и ParentClass и ChildClass.
  • Возможность построения запросов относительно указанного типа. Select ONLY ParentClass вернет только ParentClass без ChildClass.
  • Поддерживается частичный возврат объектов. Например, если вам требуется класс ForumTopic, тогда можно не подтягивать все ссылки на ForumMessages.
  • Можно указать глубину объекта для возврата в запросе.
  • Клиент-серверная архитектура.
  • Возможность одновременной работы с несколькими пользователями. Запросы выполняются одновременно и независимо.
  • Аутентификация через Windows аккаунты или через механизмы Eloquera.
  • Поддержка х86 и х64.
  • Уникальные идентификаторы для каждого объекта – отлично подходит для работы в системах не хранящих состояние и ASP.NET.
  • Поддержка культур. Например WHERE dates BETWEEN['en-US'] @d1 and @d2 будет интерпретировано в US формате, даже если текущий язык системы русский.
  • Нестрогий поиск c использованием конструкции ALMOST.
  • Хранимые процедуры.
13Июл/110

MS SQL 2011 (Denali) – Автономная база данных

В течение последних лет Microsoft внедрила множество интересных технологий, которые прочно вошли в арсенал разработчиков. Кардинальные изменения были включены в SQL Server 2005, после чего SQL Server 2008 развил и укрепил успех. Denali несет в себе множество новых инструментов, а так же расширений функционала для существующих. В этой статье в деталях рассмотрим один из новых инструментов, который, я уверен, придется по душе разработчикам баз данных. Этот инструмент, фича ­ – автономные базы данных (Contained Database). Рассмотрим что они собой представляют, как с ними работать, к чему можно применить и другие вещи.

Что не так с текущими базами?

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

Вот некоторые из ключевых проблем:

  • Потеря информации во время разворачивания базы или передвижения ее между серверами.
    Во время передвижения базы данных между серверами, то такая информация как логины, пароли, агенты заданий и прочее не может быть передвинуто вместе с базой. Потому что эта информация принадлежит серверу баз данных.  Пересоздание упомянутых объектов  руками не самое приятное занятие, которое к тому же занимает много времени и не гарантирует защиты от ошибок.
  • Различия между Разработкой и Разворачиванием приложений.
    При разворачивании приложения разработчиков могут поджидать самые разные неприятности, начиная от несовпадения тонких настроек окружения, таких как разрешения на создание новых логинов, отключенная командная строка (xp_cmdshell), языковые настройки сервера.
  • Вопросы безопасности в администрировании приложения.
    Весьма сложно администрировать и поддерживать отдельно стоящую базу данных из-за того, что, например, агенты задач доступны в пределах всего сервера, что влечет за собой повышение привилегий отдельно взятых пользователей. Однако эти повышенные права дают доступ к другим частям сервера, которые не желательно открывать. Все это может вести к серьезным проблемам безопасности.

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

11Июл/110

MS SQL 2011 (Denali) – With Result Set

Модификация возвращаемого набора данных (NEW)

В оригинальном звучании и в жизни эта возможность звучит как With Result Set. Эта штука позволяет менять имена и типы данных в возвращаемом хранимой процедурой наборе данных.

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

Для демонстрации работы будем использовать в качестве примера таблицу tbl_Test состоящую из 3 колонок.