Разработка базы данных для агрегированных баз данных
Что мне нужно учитывать в дизайне базы данных для нового приложения, которое должно поддерживать самые распространенные системы реляционных баз данных (SQL Server, MySQL, Oracle, PostgreSQL...)?
Это даже стоит усилий? Каковы подводные камни?
Ответы
Ответ 1
Короткий ответ заключается в том, чтобы придерживаться функций, которые являются стандартными или близкими к стандартным реализациям. Это более подробно:
-
Избегайте всего, что использует процедурный язык базы данных (хранимые процедуры или триггеры), так как именно здесь происходят огромные различия между системами. Возможно, вам придется использовать их для эмуляции некоторых функций, но не используйте их для создания вашей собственной функциональности.
-
Отдельные последовательности полей автоматического приращения из самих полей. Это будет немного зависеть от MSSQL, но будет реализовано в Oracle, DB/2 и т.д. Без каких-либо исправлений эмуляции.
-
Держите поля char и varchar ниже минимального максимального размера для набора движков, на которые вы нацеливаетесь.
-
Когда вы пишете запросы, используйте полный синтаксис JOIN и скопируйте JOIN, чтобы каждое объединение было между отдельной таблицей и заключенным в скобки выражением.
-
Сохранять логику обработки даты в коде, а не в запросах, поскольку многие функции даты не входят в стандарт. (Например: если вы хотите получить материал за последние две недели, подсчитайте дату две недели назад в коде и используйте это в запросе.)
Помимо того, что прилагаемые усилия не должны быть слишком пугающими, поэтому это может стоить того.
Ответ 2
В настоящее время я поддерживаю Oracle, MySQL и SQLite. И, честно говоря, это сложно.
Некоторые рекомендации:
- избегайте хранимых процедур, но вам может понадобиться их эмуляция отсутствующих функций на какой-либо платформе (см. ниже).
- узнайте, как использовать триггеры, потому что вам нужно будет имитировать недостающие функции (например, с Oracle у вас нет автоматического увеличения, поэтому вам нужно эмулировать его, и хороший выбор - с триггерами)
- имеют достойную тестовую среду, потому что вам нужно будет протестировать множество SQL, прежде чем зная, что он делает то, что вы делаете на всех своих платформах.
Стоит ли того... хорошо. Коммерчески это стоит того, что касается приложений уровня предприятия, но для блога или веб-сайта вы можете также использовать одну платформу, если сможете.
Ответ 3
Если бы я был вами, я бы думал о возврате ваших инвестиций здесь.
Всегда звучит отличная идея, чтобы иметь возможность подключаться к любой задней части или менять концы, когда захотите, но это очень редко происходит в The Real World в моем опыте.
Может оказаться, что вы можете охватить 95% потенциальных клиентов, поддерживая только Oracle и SQL Server (или MySQL и SQL Server, или... и т.д.).
Сделайте свое исследование, прежде чем идти дальше, и удачи!
Ответ 4
Я собираюсь заглянуть в johnstok ответ 1) Не использовать хранимые процедуры и 2) Не использовать SQL-сервер поставщика и добавлять к нему.
Вы также спросили: "Это даже стоит усилий?". Я бы сказал... может быть. Я написал отладчик ошибок с открытым исходным кодом BugTracker.NET, основанный на SQL Server. Есть много разработчиков, которые просто не попробовали бы, потому что им нравится придерживаться тех технологий, которым они удобны. И когда я рассматривал возможность запуска службы хостинга, я заметил, что выделенные виртуальные серверы Linux намного дешевле, чем Windows (не виртуальные) сервисы. Я мог теоретически запустить С# под моно, но мой SQL - это специфический SQL Server (хотя я не использую хранимые procs), это было бы огромным усилием для порта.
Если вы ориентируетесь на бизнес/корпоративный рынок, вы обнаружите, что некоторые магазины являются жесткими Oracle или строго SQL Server, и что ваше приложение может быть исключено в начале раунда конкурса на основе технологии, которую она использует.
Итак, может быть, что-то открытое имеет значение, для вас. Что это за приложение? Кто его будет использовать?
Вы также спросили: "Что такое ptifalls". Не тестируйте, когда идете вперед. Если вы планируете поддерживать 4 dbs, которые вы указали, то вы должны проходить тестирование с ними рано и часто, а не просто нацеливаться на них, думая, что их легко конвертировать в другие. К тому времени вы можете оказаться в архитектурном тупике.
Ответ 5
В 2001 году я работал над продуктом, который должен был поддерживать Oracle 8, MS SQL Server 2000 и MS Jet 3.51 (a.k.a. Access97). Теоретически мы могли бы использовать специалистов для каждого из этих продуктов и процесс тестирования, который обеспечивал бы получение всех одинаковых результатов. На практике наблюдалась тенденция к наименьшему общему знаменателю.
Один из подходов заключался в создании связанных таблиц в Access/Jet для Oracle и SQL Server, а затем исключительно для написания Jet SQL. Проблема здесь в том, что синтаксис Jet SQL очень ограничен.
Другой подход (обычно используемый даже в системах, которые когда-либо использовали только один продукт СУБД!) - это попытка сделать больше работы, которая действительно должна быть в интерфейсе, что должно быть доменом СУБД. Проблема здесь в том, что это часто катастрофично в отношении целостности данных. Я уверен, что вы знаете ситуацию: приложение должно воздерживаться от написания незаконных данных, но без ограничений в самой СУБД она широко раскрыта для ошибок приложений. И тогда есть пользователь, который знает, как подключиться к данным через Excel, SQL Management Studio и т.д., И тем самым полностью обходить приложение, которое должно обеспечить целостность данных...
Лично я обнаружил, что все чаще пишу код на скользящей шкале того, что я только позже обнаружил, назывался "переносимостью". В идеале, в первом случае код 'vanilla' понимается всеми СУБД, которые мы поддерживали, и при этом я обнаружил стандарты SQL-89 и SQL-92. Далее был код SQL, который можно легко перевести (возможно, используя код) для каждой СУБД, например. Oracle использовал этот ужасный встроенный синтаксис внешнего соединения, но существовало понятие внешнего соединения; Oracle и SQL Server использовали SUBSTRING, но Jet требовал, чтобы ключевое слово было MID $; и т.д. Наконец, есть вещи, которые просто должны быть специфичными для реализации, очевидно, избегать, если это вообще возможно, при этом все еще уделяя должное внимание целостности данных, функциональности и производительности.
К счастью, за прошедшие годы продукты приближаются к стандартам ANSI SQL (кроме Jet, который устарел MS, теперь поддерживается группой MS Access, которая, как представляется, сокращает основные функции, такие как безопасность и репликация). Поэтому я по-прежнему привык писать стандартный SQL, если это возможно.
Ответ 6
В одном ответе люди часто говорят, что вы не должны использовать SQL-код, специфичный для базы данных, и просто код для стандартов ansi. Они часто говорят только о разговоре с базой данных через хранимые процедуры для абстрагирования любого sql. Это неправильные ответы и только приводят к боли. Кодирование на "стандартный" sql практически невозможно, поскольку каждый поставщик имеет такие разные интерпретации.
Что вам нужно, чтобы иметь какой-то уровень стойкости базы данных, абстрагирует различия между базами данных (извините johnstock, это почти то, что вы сказали). Есть много других ORM и подобных продуктов, чтобы сделать это для каждой платформы,
Ответ 7
Сохранять имена полей и таблиц короткими (< 30 символов) и регистрозависимыми. например TABLE_NAME и FIELD_NAME
Ответ 8
95% портативный почти такой же удобный, как и переносимый, если вы можете изолировать зависящий от платформы код на определенный уровень. Так же, как Java описывается как 'Write once test везде', нужно еще раз протестировать приложение на каждой платформе, на которой вы собираетесь ее запускать.
Если вы относитесь к своему конкретному коду платформы, вы можете использовать переносимый код для 95%% функциональности, которая может быть выполнена адекватно переносимым образом. Остальные части, которые необходимо выполнить в хранимой процедуре или другой платформозависимой конструкции, могут быть встроены в ряд модулей, зависящих от платформы, к стандартному интерфейсу. В зависимости от платформы вы используете модуль, соответствующий этой платформе.
В этом разница между "Test везде" и "Build platform specific modules and Test повсюду". В любом случае вам нужно будет протестировать все поддерживаемые платформы - вы не можете уйти от этого. Дополнительная сборка относительно небольшая и, вероятно, меньше, чем создание действительно запутанной архитектуры, чтобы попытаться сделать все это полностью портативно.
Ответ 9
В дополнение к этому ответу, и, как правило, не позволяйте серверу генерировать или вычислять данные. Всегда отправляйте прямые инструкции SQL, за исключением формул. Не используйте значения по умолчанию (или делайте их базовыми, а не формулами). Не используйте правила валидации
Оба значения по умолчанию и правила проверки должны быть реализованы на стороне клиента.
Ответ 10
- Не используйте хранимые процедуры
- Не используйте специальные SQL-запросы поставщика
Или используйте технологию сохранения, такую как hibernate/nHibernate, которая абстрагирует различия между различными БД.
Ответ 11
Исследование начинается с самого низкого общего знаменателя для типов данных. Например, SQL Server имеет целое число, но Oracle использует число.
Ответ 12
Я понимаю другие ответы здесь, но почему бы не использовать хранимые процедуры? Это так, что логика не скрыта?
Ответ 13
Также, принимая во внимание множество хороших и разумных ответов, я бы добавил, что что-то вроде миграции ActiveRecord (из Ruby В Rails, но вы можете просто использовать библиотеку), может быть полезно. Он абстрагирует такие вещи, как создание/изменение таблицы, соответствующие типы столбцов, упрощение управления индексами и (до определенной степени) последовательность на довольно простой описательный язык.
Хранимые процедуры и триггеры в значительной степени игнорируются, но если вы собираетесь использовать кросс-платформу, такая функциональность, вероятно, должна быть в слое кода.
Из любопытства я переключился между Oracle, MS SQL, MySQL и SQLite с одним и тем же набором миграций, и самая худшая проблема, с которой я столкнулся, заключалась в том, что я должен был убедиться, что имена столбцов и таблиц не состоят в объединении зарезервированного слова списки через БД.
Ответ 14
Правило 1: Не используйте функции, специфичные для базы данных
Правило 2: Не используйте хранимые процедуры.
Правило 3: Если вы нарушите правило 1, то также разбейте правило 2.
Было много комментариев об использовании хранимых процедур. Это связано с тем, что синтаксис/семантика очень разные, поэтому переносить их сложно. Вам не нужны кучи кода, которые вы переписали и повторили.
Если вы решите, что вам нужно использовать специфичные для базы данных функции, вы должны скрыть эти данные за хранимой процедурой. Вызов хранимых процедур из разных баз данных довольно схож. Внутри процедуры, которая написана в PL/SQL, вы можете использовать любые конструкторы Oracle, которые вы найдете полезными. Затем вам нужно написать эквивалент для других целевых баз данных. Таким образом, части, специфичные для базы данных, находятся только в этой базе данных.
Ответ 15
Если это вообще возможно, я бы этого не сделал. Я работал с несколькими из этих баз данных в прошлом, и они были ужасно медленными (один особенно болезненный пример, который я могу представить, - это приложение для колл-центра, которое заняло десять минут, чтобы переместиться с одного экрана на другой в напряженный день) из-за необходимости написать общий код sql и не использовать настройку производительности, которая лучше всего подходит для конкретной бэкэнд.
Ответ 16
Первое, что нужно учитывать, - это то, что стоимость самостоятельной работы ниже, чем зависит от базы данных. Я думаю, что несколько раз важно для некоторых продуктов, которые хотят дать выбор клиентам, но они теряют множество функций базы данных (это значит, что код будет написан снова).
Для крупных клиентов (больших приложений) они должны полностью зависящие от базы данных. Для небольших настроек возникает проблема, когда Oracle XE и MySQL на одном сервере (или два).
Действительно, я предпочитаю использовать более одной базы данных и что приложение знает, какая база данных является кодом "abastract".
Ответ 17
IMO зависит от типа приложения, которое вы разрабатываете:
- Приложение, которое выполняет некоторую другую потребность, которая связана с хранением данных, например. коммерческие сайты, бизнес-приложения, даже приложения для дома/образа жизни.
- Приложение, специально разработанное для управления или администрирования баз данных, например. инструменты проектирования, инструменты моделирования, инструменты ETL.
В случае 1 просто выберите одну СУБД, которая наилучшим образом соответствует вашим потребностям, и код против этого, используя полную мощность всех своих проприетарных функций.
В случае 2 вы, скорее всего, обнаружите, что вполне возможно придерживаться общего поднабора операций, поддерживаемого всеми СУБД, которые вы собираетесь поддерживать.