2009-05-28 2 views
1

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

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

CREATE TABLE 'Tables' (
    Id INT NOT NULL PRIMARY KEY, 
    NAME VARCHAR(255) 
) 

CREATE TABLE 'TableColumns' (
    Id INT NOT NULL PRIMARY KEY, 
    TableId INT NOT NULL FOREIGN KEY ON 'Tables', 
    NAME VARCHAR(255) 
) 

CREATE TABLE 'TableRows' (
    Id INT NOT NULL PRIMARY KEY, 
    TableId INT NOT NULL FOREIGN KEY ON 'Tables', 
    RowNumber INT NOT NULL 
) 

CREATE TABLE 'TableValues' (
    RowId INT NOT NULL PRIMARY KEY, 
    ColumnId INT NOT NULL PRIMARY KEY, 
    Value VARCHAR(255) 
) 

(обратите внимание, что таблица TableValues ​​имеет 2 поля первичного ключа здесь, он должен представлять собой «композитный» первичный ключ, не слишком заморачиваться с тем, что мой синтаксис не является законным SQL, это просто должно показать идею).

Я провел немного тестирования с этим и смог успешно выполнить простой запрос (простая фильтрация, упорядочение и т. Д.). Мой способ сделать это - сначала запросить таблицу TableRows - для фильтрации я затем отфильтровал строки, столбцы которых не соответствовали критериям, и для сортировки я отсортировал RowIds на основе содержимого их столбца (как указано в указанной сортировке). Получив список идентификаторов строк в нужном порядке, отсюда он просто должен был выбрать, что нужно.

Все это прекрасно работает, но я немного застрял здесь. Я хотел бы как-то быть в состоянии представлять разные типы данных (что действительно является моей основной проблемой), а также позже выработать, как выполнять объединения.

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

Я знаю, что всегда мог бы просто создавать таблицы в своей базе данных с запросами, созданными на лету в C#, чтобы выполнить это, и аналогичным образом использовать только SQL-запросы - однако я никогда не был большим поклонником предоставления пользователям «конструкции», запросы к моей базе данных похожи на это - и мне кажется, что это приведет к тому, что это приведет к тому, что появится много ошибок - и в худшем случае в конечном итоге это позволит пользователю так или иначе убить базу данных.

Кроме того, моя проблема заключается в том, как я могу справиться с этим так, чтобы иметь смысл с точки зрения C#. До сих пор я думаю, что я склонен к использованию LINQ, а затем создаю свои собственные методы расширения, которые будут применять необходимую функциональность - это ExtensionMethods, расширяющие IQueryable.

Так что мне бы хотелось, чтобы некоторые идеи о том, как это можно сделать, идеи о том, как настроить производительность, идеи о том, как обращаться с отдельными типами данных в таблице (естественно, сохраните тип в таблице column , но как фактически сохранить значение, чтобы я мог фильтровать, сортировать и т. д.? - без добавления столбца «TextValue», «MoneyValue» и так далее в таблицу table table). И последнее, но не менее важное, надеюсь, здесь будут хорошие дискуссии - я, по крайней мере, считаю это интересной темой.

+14

Я голосую за вас в качестве стимула отправить это на http://www.thedailywtf.com – TheTXI

+1

Как говорит TheTXI, мы видим эту «схему» все время на The Daily WTF. Это невероятно плохая идея. И веселый. – Welbog

+1

У меня была идея, что это будет плохая схема, и именно поэтому я разместил здесь - чтобы получить некоторые идеи о том, как улучшить идею. Я забочусь о том, что могу сделать, а не о том, будет ли это сделано так или иначе. А также, я забочусь о обучении :). – kastermester

ответ

9

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

Кажется правильным, он должен работать.

Это будет. Вроде.

Отзывы о TheDailyWTF имеют смысл. Повторная реализация СУБД поверх СУБД на самом деле не очень хорошая идея. Отправляясь мета как это собирается дать вам

  • Согласовать underperfoming систему
  • поддерживающую кошмар

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

Есть несколько примеров такого рода системы, которые я знаю:

  • Microsoft OSLO (в частности Repository системы)
  • архитектуры ASAM-ODS сервера (обратите внимание на пакет ASAM-ODS)

И я уверен, что есть другие.

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

Я действительно сильно чувствую единственный правильный ответ на вид системы, которую вы предлагаете, это не.

+0

Спасибо, я загляну в него :). – kastermester

+0

Привет, Денис, я хотел бы задать вам несколько вопросов об ASAM, если у вас есть немного времени для меня, это было бы хорошо. Не стесняйтесь вступать в комнату [ASAM] (http://chat.stackoverflow.com/rooms/81001/asam) –

2

С риском кучки downvotes, почему бы просто не установить их MS Access?

+1

Это предназначено как веб-приложение, а не приложение для рабочего стола - и почему бы не создать веб-страницу, которая говорит людям использовать MS Access? - Потому что моя мама не будет, моя сестра не будет, и, честно говоря, никто, кого я знаю, не думает, что компьютеры умиротворяют. – kastermester

+2

@kastermester: Затем я отправил их в google docs. – GEOCHET

+2

@kaster: достаточно справедливо, но я все равно сохраню свой ответ, так как это может помочь кому-то придумать лучший ответ для вас. – belgariontheking

1

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

1

Я не уверен, почему вся ненависть и никто на самом деле не пытается ответить на ваш вопрос. Даже если это, в конечном счете, вопрос о том, как вы будете внедрять Google Docs, это еще справедливый вопрос.

Предполагая, что вы уже продумали, действительно ли вы хотите сделать это (то, что я предполагаю, что все ненавидят о), то здесь, по крайней мере, лучше:

DATA_TABLE { 
    TABLEID INT, 
    INT1 INT, 
    INT2 INT, 
    VARCHAR1 VARCHAR(255), 
    ... etc 
} 

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

Этот подход может работать отлично (я могу подтвердить, что многие успешные сайты .com использовали эту схему, как с тем, с кем я был связан, и/или знали людей, которые были), но для достижения оптимальной производительности я бы рекомендовал используя CHAR более VARCHAR, совместив свои кортежи, чтобы они поместились на страницах ну и т.д.

Я думаю, что это справедливо (очень) похож на dsteele ответим

+0

Спасибо Мэтту, это выглядит как интересная и многообещающая идея - я буду изучать это. – kastermester

+0

Стоит отметить, что каждый дизайн имеет компромиссы. Другие люди предлагали просто создавать таблицы. Это вводит конфликты имен, если вы не создаете схемы/пользователей для каждого пользователя. В зависимости от того, сколько (устаревших) пользователей и таблиц вы получите, есть затраты на обслуживание, связанные с каждым дизайном – Matt

+0

Я не уверен, что понимаю этот ответ? Если все сопоставлено с моей data_table, как узнать, сколько полей у меня есть, какие типы и т. Д. Если вы не рекомендуете data_table для пользователя/случая использования? –

6

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

  • А как насчет использования XML? Разрешить каждому пользователю хранить XML-файл на «таблицу» и просто поддерживать его схему. Каждая «строка» будет элементом XML с дочерними элементами. Вы можете по желанию привязать XML в SQL или просто сохранить его другими способами. Это не очень хорошо работает с большими наборами данных, но для тысяч записей это удивительно быстро; Я провел несколько тестов с 20 + МБ XML-файлами на C# и смог их создать, прочитать и проанализировать их менее чем за 1 секунду. Используя LINQ to XML, вы даже можете построить довольно сложные запросы и объединения. Я бы не использовал XML для крупной корпоративной системы, но вы были бы удивлены, как далеко он пойдет на современных машинах с большим количеством памяти и быстрыми процессорами - и он бесконечно гибкий.
  • Не могли бы вы использовать объектно-ориентированную базу данных (Matisse и т. Д.)? У меня нет опыта в этом, но я думаю, что вы можете легко сделать что-то вроде XML-подхода, но с лучшей производительностью.
  • Amazon Simple DB: Если я правильно помню, это, по сути, база данных на основе имени/значения, которую вы можете использовать. Может ли ваше приложение использовать это в фоновом режиме вместо этого, чтобы избежать необходимости иметь дело со всей сантехникой? Если вам нужно было заплатить за SQL Server, то Amazon DB может быть дешевле и иметь мышцы, чтобы масштабировать большие, но без некоторых из таких вещей, как реляционные запросы.
+0

Здесь вы задали очень интересные идеи, и я не могу поверить, что не думал о Прежде всего, я обязательно буду в этом разбираться. – kastermester

+0

Хорошая идея о системе пары Key/Value. Я не столько с вами на XML, хотя, особенно потому, что kastermester упоминал о поддержке потенциально довольно большого количества строк. Использование XML потребует загрузки/сохранения всего файла для каждого небольшого обновления, которое может оказаться непомерно высоким. –

+0

Для больших наборов XML будет запретительным, но для 1000/2000 записей, вероятно, хорошо; Я обнаружил, что C# невероятно быстро работает с XML. Моя тестовая программа будет читать 20 МБ XML-файл (10 000 "записей"), оценивать каждый узел и выводить его в файл CSV менее чем на 0,4 с на моем ноутбуке. Я бы оценил половину времени, которое фактически потрачено на запись CSV-файла. Я думаю, что SQL имеет встроенную обработку запросов внутри XML-файлов, которые могут быть быстрее. – Frans

1

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

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

Теперь я знаю, что это противоречит всей практике базы данных, но я денормализовал данные для каждой «Таблицы», как у вас есть, и физически создал таблицу в базе данных Table_1, Table_2.

Я создал и опустил Table_1 и Table_2 на основе триггеров в таблице Таблицы, я добавил и удалил столбцы в эти таблицы с помощью триггеров в таблице TableColumns, вставил и удалил строки с помощью триггеров в таблице TableRows и обновил значения с помощью триггеров в таблице TableValues.

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

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

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

3

Дизайн, который вы показываете в своем оригинальном вопросе, является вариантом дизайна Entity-Attribute-Value.

Ожидание, которое некоторые люди выражают, вероятно, связано с тем, что практически каждый разработчик баз данных «обнаруживает» этот проект и пытается использовать его именно для того, для чего вы его используете, - гибкую систему для поддержки расширяемой базы данных без неудобства использования CREATE TABLE и ALTER TABLE.

Но EAV имеет много недостатков.Вот только один: как бы вы сделали любой заданный столбец обязательным (эквивалент ограничения NOT NULL)?

Реляционная база данных предполагает, что вы знаете таблицы спереди, и вы можете определить их. RDBMS не является правильным инструментом для полностью динамических отношений или отношений с полностью переменными наборами атрибутов. Для этого существует ряд других технологий, таких как XML, RDF или CouchDB.

См. Также мой ответ на «The Next-gen Databases».

0

Вы определенно хотите упростить это - разрешите пользователям создавать таблицы, возможно, в TEMPDB. Просто добавление суффикса схемы к таблицам «CREATE TABLE» d позволит вам избежать необходимости добавления их в таблицы REAL системы. Легко для вас также фильтровать их. Проблема в том, что большинство баз данных не позволят не-dba создавать таблицы, поэтому для этого требуется некоторая предварительная настройка. Вы даже можете создать схему в своей базе данных специально для этого и установить ограничения на размер и ограничения размера таблицы, если ваша база данных поддерживает их.

Не изобретайте велосипед.

Сделайте это так, и вы автоматически получите соединения, союзы и т. Д. И интерфейсы с Crystal Reports и другими инструментами, которые не требуют grokkin 'вашей конкретной схемы.

0

SharePoint делает это и многое другое поверх SQL Server. Я бы исследовал, как SharePoint использует SQL Server.

Смежные вопросы