Проектирование базы данных для приложений, не зависящих от базы данных - PullRequest
15 голосов
/ 15 октября 2008

Что я должен учитывать при проектировании базы данных для нового приложения, которое должно поддерживать самые распространенные системы реляционных баз данных (SQL Server, MySQL, Oracle, PostgreSQL ...)?

Стоит ли даже усилий? Какие подводные камни?

Ответы [ 17 ]

15 голосов
/ 15 октября 2008

Краткий ответ - придерживаться стандартных или близких к стандартным функциям. Что это значит более подробно:

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

  • Отделите последовательности полей с автоинкрементом от самих полей. Это будет выглядеть немного принудительно для MSSQL, но будет реализовано чисто в Oracle, DB / 2 и т. Д. Без необходимости исправлений эмуляции.

  • Держите поля char и varchar ниже наименьшего максимального размера для набора двигателей, к которому вы стремитесь.

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

  • Сохраняйте логику обработки даты в коде, а не в запросах, поскольку многие функции даты находятся за пределами стандарта. (Например: если вы хотите получить данные за последние две недели, рассчитайте дату две недели назад в коде и используйте ее в запросе.)

Помимо этого, прилагаемые усилия не должны быть слишком пугающими, поэтому вполне могут стоить того.

6 голосов
/ 15 октября 2008

Если бы я был на вашем месте, я бы задумался о возврате ваших инвестиций здесь .

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

Может оказаться, что вы можете охватить 95% своих потенциальных клиентов, поддерживая только Oracle & SQL Server (или MySQL & SQL Server, или ... и т. Д.).

Проведите исследование, прежде чем идти дальше , и удачи!

6 голосов
/ 15 октября 2008

В настоящее время я поддерживаю Oracle, MySQL и SQLite. И, честно говоря, это сложно. Вот некоторые рекомендации:

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

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

4 голосов
/ 15 октября 2008

В 2001 году я работал над продуктом, который должен был поддерживать Oracle 8, MS SQL Server 2000 и MS Jet 3.51 (например, Access97). Теоретически мы могли бы нанять специалистов для каждого из этих продуктов и провести процесс тестирования, обеспечивающий одинаковые результаты. На практике наблюдалась тенденция к наименьшему общему знаменателю.

Один из подходов заключался в создании связанных таблиц в Access / Jet для Oracle и SQL Server, а затем исключительно в написании Jet SQL. Проблема в том, что синтаксис Jet SQL очень ограничен.

Другой подход (обычно используемый даже в системах, в которых когда-либо использовался только один продукт СУБД!) - попытаться выполнить больше работы, которую действительно следует выполнять во внешнем интерфейсе, то есть вещи, которые должны входить в состав СУБД. Проблема здесь в том, что это часто приводит к катастрофическим последствиям в отношении целостности данных. Я уверен, что вы знаете ситуацию: приложение должно воздерживаться от записи недопустимых данных, но без ограничений в самой СУБД оно широко открыто для ошибок приложения. Кроме того, есть пользователь, который знает, как подключиться к данным через Excel, SQL Management Studio и т. Д. И, таким образом, полностью обойти приложение, которое должно обеспечивать целостность данных ...

Лично я обнаружил, что все больше и больше пишу код по скользящей шкале, и то, что я только позже обнаружил, называется «мобильностью». В идеале, во-первых, это «ванильный» код, понятный всем поддерживаемым нами СУБД, и при этом я обнаружил стандарты SQL-89 и SQL-92. Затем был SQL-код, который можно было легко перевести (возможно, с помощью кода) для каждой СУБД, например. Oracle использовал этот ужасный инфиксированный синтаксис внешнего соединения, но концепция внешнего объединения была там; Oracle и SQL Server использовали SUBSTRING, но Jet требовал, чтобы ключевое слово было MID $; и т. д. Наконец, есть вещи, которые просто должны зависеть от реализации, и, очевидно, их следует избегать, если это вообще возможно, при этом должным образом учитывая целостность данных, функциональность и производительность.

К счастью, за прошедшие годы продукты приближались к стандартам ANSI SQL (кроме Jet, который MS устарел, теперь он поддерживается только командой MS Access, по-видимому, сокращая основные функции, такие как безопасность и репликация). ). Поэтому я сохранил привычку писать стандартный SQL, где это возможно.

4 голосов
/ 15 октября 2008

Я собираюсь рекламировать ответ johnstok на 1) Не используйте хранимые процедуры и 2) Не используйте специфичный для поставщика SQL и добавьте к нему.

Вы также спросили: «Стоит ли даже усилий?». Я бы сказал ... возможно. Я написал трекер ошибок с открытым исходным кодом BugTracker.NET, основанный на SQL Server. Есть много разработчиков, которые просто не хотели бы попробовать, потому что им нравится придерживаться технологий, которые им удобны. И когда я подумывал о запуске службы хостинга, я заметил, что выделенные виртуальные серверы Linux намного дешевле, чем службы Windows (не виртуальные). Теоретически я мог бы запустить C # под моно, но мой SQL настолько специфичен для SQL Server (даже если я не использую хранимые процедуры), это было бы огромным усилием для переноса.

Если вы нацелены на бизнес / корпоративный рынок, вы обнаружите, что некоторые магазины - это строго Oracle или строго SQL Server, и что ваше приложение может быть исключено на ранних этапах конкурса на основе технологии, которую оно использует. .

Так что, может быть, открытость имеет значение для вас. Что это за приложение? Кто будет этим пользоваться?

Вы также спросили: «Что такое Птифоллс». Не проверяю, как вы идете вместе. Если вы планируете поддерживать 4 дБ, которые вы перечислили, то вам следует тестировать их рано и часто, а не просто нацеливать, думая, что будет легко перейти на другие. К тому времени вы можете оказаться в архитектурном тупике.

4 голосов
/ 15 октября 2008

Люди часто говорят вам, что не следует использовать специфичные для базы данных sql и просто кодировать в соответствии со стандартами ANSI. Они часто говорят, что говорят только с базой данных через хранимые процедуры, чтобы абстрагировать любой SQL. Это неправильные ответы и ведут только к боли. Кодирование в «стандартный» sql практически невозможно, потому что у каждого поставщика такие разные интерпретации.

То, что вам нужно, это иметь некоторый слой сохраняемости базы данных, который абстрагирует различия между базами данных (извините, Джонсток, это почти именно то, что вы сказали). Есть много других ORM и аналогичных продуктов, которые делают это для каждой платформы,

2 голосов
/ 15 октября 2008

Имена полей и таблиц должны быть короткими (<30 символов) и без учета регистра. например TABLE_NAME и FIELD_NAME </p>

1 голос
/ 18 октября 2008

В дополнение к этот ответ и, как правило, не позволяет серверу генерировать или вычислять данные. Всегда отправляйте прямые инструкции SQL, исключая формулы. Не используйте свойства значений по умолчанию (или делайте их базовыми, а не формулами). Не используйте правила проверки Как значения по умолчанию, так и правила проверки должны быть реализованы на стороне клиента.

1 голос
/ 15 октября 2008

95% переносимость почти так же хороша, как переносимость, если вы можете выделить зависимый от платформы код в определенный уровень. Подобно тому, как Java был описан как «Писать один раз тест везде» , все равно нужно тестировать приложение на каждой платформе, на которой вы собираетесь его запускать.

Если вы осмотрительны в отношении кода, специфичного для вашей платформы, вы можете использовать переносимый код для 95 +% функциональности, которая может быть адекватно реализована переносимым способом. Остальные части, которые должны быть выполнены в хранимой процедуре или другой платформо-зависимой конструкции, могут быть встроены в серию платформо-зависимых модулей для стандартного интерфейса. В зависимости от платформы вы используете модуль, соответствующий этой платформе.

В этом разница между «Тестировать везде» и «Создавать модули для платформы и тестировать везде». В любом случае вам нужно будет протестировать на всех поддерживаемых платформах - вы не можете избежать этого. Дополнительная сборка относительно незначительна, и, вероятно, меньше, чем создание действительно запутанной архитектуры, чтобы попытаться сделать эти вещи полностью переносимыми.

0 голосов
/ 16 октября 2008

Если это вообще возможно, я бы избегал этого. В прошлом я работал с несколькими из этих баз данных, и они были ужасно медленными (один особенно болезненный пример, который я могу вспомнить, - это приложение для колл-центра, которому потребовалось десять минут для перехода с одного экрана на другой в напряженный день) из-за необходимости написать общий SQL и не использовать настройку производительности, которая была лучшей для конкретного бэкэнда.

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