Вопрос

Для небольшого проекта мне нужно использовать простую базу данных с очень легкими требованиями:несколько таблиц, всего не более нескольких тысяч записей, 2 или 3 пользователя.Я работаю в среде .NET.

Поскольку сервер базы данных (даже в версиях Express) в этом случае кажется огромным излишним, очень простая база данных MDB могла бы удовлетворить большинство требований.Однако меня беспокоит параллелизм.Моя идея состоит в том, чтобы разместить файл .mdb в общей сетевой папке и предоставить пользователям доступ к этому файлу из своих клиентов на базе .NET.БД в основном предназначена для операций только для чтения, но пользователям иногда также необходимо обновлять/удалять записи.Если в данный момент это будет невозможно (из-за блокировки базы данных или чего-то еще), я могу сохранить обновления на клиенте и обработать их позже.

Сам вопрос идет по следующим пунктам:

  • Как в MDB обрабатываются параллельные чтения?
  • Как в MDB обрабатываются одновременные обновления/удаления?
  • Существует ли концепция блокировок и как ее использовать в приложении .NET?
  • Размещение файла MDB на сетевом ресурсе — хорошая или ужасная идея?

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

РЕДАКТИРОВАТЬ:Возможно, это мое плохое описание проблемы, но большинство ответов, похоже, советуют использовать полноценный сервер БД.Я понимаю различия и преимущества установки сервера и фактически реализовал немало проектов на MSSQL и Oracle.Однако в этом вопросе меня интересует только Access и его проблемы параллелизма, поэтому, пожалуйста, не предлагайте сервер базы данных.

Спасибо за вашу помощь.

Это было полезно?

Решение

Это старый вопрос, но никто на него так и не ответил.Вот вопросы:

  1. Как в MDB обрабатываются параллельные чтения?
  2. Как в MDB обрабатываются одновременные обновления/удаления?
  3. Существует ли концепция блокировок и как ее использовать в приложении .NET?
  4. Размещение файла MDB на сетевом ресурсе — хорошая или ужасная идея?

На первые два вопроса можно ответить одним объяснением.Здесь есть одно ключевое предостережение:ответы, которые я даю здесь, относятся к Jet MDB (и их вариантам) и не полностью применимы к новому формату файлов, представленному начиная с A2007, то есть к формату ACCDB.Я не полностью изучил последствия удаления Jet ULS из ACE, и некоторые из комментариев ниже могут предполагать, что Jet ULS находится под капотом.Однако во многих случаях вы можете заменить «файл LDB» на «файл LACCDB», и результаты будут такими же.

1-2) Параллельное чтение/обновление/удаление

Ядро базы данных Jet часто называют базой данных «файлового сервера», поскольку на сервере нет демона, управляющего вводом-выводом с файлами данных на сервере.Это означает, что все клиенты, использующие Jet MDB, читают файл напрямую.

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

Jet использует файл блокировки записей, где, если ваш MDB — «MyFile.MDB», файл блокировки записей будет находиться в той же папке и называться «MyFile.LDB».В файле LDB записаны сведения о том, у каких пользователей Jet ULS открыт файл MDB, с какой рабочей станции подключен этот пользователь, а также вся информация, необходимая для согласования проблем параллелизма.

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

В файле базы данных Jet блокировки применяются либо к страницам данных (которые в Jet 4 были увеличены до 4 КБ, тогда как в Jet 3.x и ранее они были 2 КБ), либо на уровне записи, если таблица данных изначально создавалась для использовать блокировку на уровне записи.На заре Jet 4 многие считали, что блокировка на уровне записей работает довольно медленно, особенно при использовании пессимистической блокировки, поэтому многие разработчики Access никогда не использовали ничего, кроме блокировки на уровне страницы (@Дэвид Фентон поднимает руку!).

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

Некоторые предостережения:

  1. из DAO блокировка на уровне записи недоступна, и вы получаете блокировку только на уровне страницы.

  2. из DAO существует ряд опций для управления оптимистической/пессимистической блокировкой, в частности аргумент LockEdits метода OpenRecordset, но он также взаимодействует с некоторыми настройками, указанными в аргументе OpenRecordset Options (например, параметр dbReadOnly нельзя использовать с LockEdits).Помимо блокировки, существуют также варианты согласованных/несогласованных обновлений, и все это может взаимодействовать с транзакциями (например, изменения в незафиксированной транзакции не будут видны другим пользователям и, следовательно, не будут конфликтовать с ними, но можно установить блокировки только для чтения для задействованных таблиц).

Из ADO/OLEDB эти структуры управления параллелизмом Jet будут сопоставлены с соответствующими функциями и аргументами, найденными в ADO/OLEDB.Поскольку я использую Jet только из Access, я взаимодействую с ним только через DAO, поэтому не могу посоветовать, как вы ими управляете с помощью ADO/OLEDB, но дело в том, что механизм базы данных Jet предлагает контроль над блокировкой вашей записи при доступе к ней. программно (в отличие от пользовательского интерфейса Access) — это просто сложнее.

3) Блокировки и .NET

Я не могу дать здесь никакого совета, кроме того, что вы, скорее всего, будете использовать OLEDB в качестве интерфейса данных, но дело в том, что функция блокировки/управление находится в самом движке базы данных, поэтому, вероятно, есть способ управлять ею через ОЛЕДБ.Однако это может быть некрасиво, поскольку мне кажется, что OLEDB спроектирован вокруг архитектуры клиент/сервер, и блокировка файлов на основе файлов Jet может не соответствовать этому элегантным образом.

4) MDB на сетевом ресурсе

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

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

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

Теперь, если вы плохо проиндексировали свои таблицы, вы можете в конечном итоге извлечь всю таблицу и выполнить полное сканирование таблицы.Аналогично, если вы основываете критерии на функциях на стороне клиента, которые не являются частью диалекта SQL Jet, вы можете в конечном итоге получить полную таблицу (сортировка, скажем, по методу replace(MyField, "A", "Z"), скорее всего, приведет к полное сканирование таблицы).Но подобные вещи также будут неэффективны с архитектурой клиент/сервер, так что это просто проект схемы, основанный на здравом смысле, чтобы правильно индексировать вещи и быть осторожным с использованием UDF или несовместимых с Jet функций.В общем, те же вещи, которые эффективны с клиентом/сервером, будут эффективны и с Jet (основное отличие состоит в том, что с Jet вам лучше использовать постоянное соединение, чтобы избежать накладных расходов на воссоздание файла LDB, что имеет существенное значение).

Еще одна вещь, которую следует избегать, — это пытаться использовать данные Jet через соединение Wi-Fi.Мы все знаем, насколько ненадежен Wi-Fi, и он просто напрашивается на проблемы при попытке работать с данными Jet через соединение Wi-Fi.

Нижняя линия:

Если вы используете MDB в качестве хранилища данных для обслуживания данных с веб-сервера, вам следует размещать данные как можно ближе к оперативной памяти веб-сервера.Это означает, что, где это возможно, на дисковом томе, подключенном к физическому веб-серверу.Там, где это невозможно, вам нужно быстрое и надежное подключение к локальной сети.Локальные сети GB в центрах обработки данных в наши дни довольно распространены, и мне было бы очень удобно работать с данными Jet через такое соединение.

Для совместного использования, например, нескольких клиентских рабочих станций, на которых запущено настольное приложение VB.NET, использующих одну базу данных Jet MDB в качестве хранилища данных, вполне безопасно хранить файл данных на надежном файловом сервере.По возможности рекомендуется размещать файлы Jet MDB на компьютерах, которые не служат нескольким целям (например, ваш контроллер домена, на котором работает Exchange, SQL Server и действует как файловый сервер и сервер печати, может быть не лучшим местом). .Такие приложения, как Exchange, могут сильно мешать работе файлового сервера, и я обычно рекомендую никогда не размещать файлы MDB на многозадачном сервере Exchange, если только его объем не очень мал.

Другие соображения:

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

  2. Я бы рекомендовал не хранить какие-либо MDB где-либо, кроме собственной файловой системы Windows, обслуживаемой через собственную сеть Microsoft SMB.Это означает отсутствие Novell, отсутствие Linux, отсутствие SAMBA.Основная причина этого заключается в том, что, по-видимому, существуют низкоуровневые перехваты Jet для некоторых низкоуровневых функций блокировки в файловой системе Windows, которые не реплицируются на 100% в других файловых системах.Я очень консервативен в этом вопросе, и многие компетентные разработчики Access сообщают об отличных результатах с правильно настроенными файловыми серверами Novell (часто необходимо внести некоторые корректировки блокировки записей, хотя в наши дни это может быть менее актуально - я не знаю). Я даже не знаю, существует ли еще Novell!), а также потрясающую производительность файловых серверов на базе Linux, работающих под управлением SAMBA.Я отношусь к этому с осторожностью и рекомендую воздержаться от этого любому клиенту (включая различные устройства SAN, поскольку не многие из них работают на базе Windows).

  3. По тем же причинам я бы никогда не запускал их в какой-либо виртуализированной файловой системе.Однако у меня есть клиентка, которая уже несколько лет запускает свое однопользовательское приложение Access под Parallels на Mac Air без единой проблемы.Но он однопользовательский, поэтому проблемы с блокировкой будут относительно незначительными.

Я не знаю, отвечает ли это на ваши вопросы или нет.Все это основано на моем 13-летнем регулярном использовании Jet в качестве разработчика Access и изучении единственной опубликованной книги по Jet — «Руководства программистов Jet Database Engine» (только для Jet 3.5).Я не предоставил никаких реальных цитат, но если кому-то понадобятся подробности того, что я сказал, я проведу исследование, если смогу.

Другие советы

За прошедшие годы я создал около дюжины приложений для малого бизнеса в Access.Большинство из них имеют максимум 10-20 пользователей одновременно.Базы данных разделены на базу данных «приложение» и базу данных «данные».Производительность достойная, проблем с параллелизмом нет.Кроме того, начиная с Access 2000 SP2 коррупция практически не существовала.

Многие люди говорят: «Никогда не используйте Access» — ну, если это сделано правильно (т. е. профессиональным разработчиком). Access — это довольно хороший пакет для разработки, и я хорошо зарабатываю на нем.Мои клиенты очень довольны тем, что я построил.

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

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

В большинстве случаев Access обеспечивает блокировку записей и файлов для некоторых DDL (например,изменения схемы) по умолчанию.

Но Microsoft фактически устаревает, и некоторые из ваших коллег будут презирать вас за его использование.

(В этот момент я обычно прячусь в укрытие и кричу «ВХОД!!!».)

Access на самом деле представляет собой настольное однопользовательское решение.На практике верхний предел пользователя составляет «один».

Это тоже местный движок.То есть, когда вы запускаете запрос, данные передаются по сети в локальный механизм JET для обработки.Файл .ldb размещается в общей сетевой папке для управления блокировками.

Если вы используете серверный движок (MSSQL, MySQL, Sybase, Orable и т. д.), вы отправляете запрос в движок, который его обрабатывает и возвращает вам результаты.Замки удерживаются внутри.

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

Если ваш пользователь решит нажать кнопку сброса, база данных Access имеет большую вероятность быть повреждена, и вам придется удалить .ldb.

При наличии подходящего ядра базы данных (MSSQL, Sybase, Orable:Мне не нравятся резервные копии MySQL), тогда у вас также есть подходящая возможность резервного копирования.Если у вас нет какого-нибудь хитрого программного обеспечения для резервного копирования используемых файлов, возможно, у вас не будет резервных копий ваших данных в базе данных Access.

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

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

Я использовал Access или, точнее, Jet в качестве серверной части на очень маленьком частном сайте, который никогда не сможет расти, поскольку он ограничен размером профессии в этой маленькой стране.За три года у меня не было никаких проблем.Пользователей менее 100, из них около тридцати-сорока используют его каждый день.Таблицы содержат несколько тысяч записей.

У меня нет большого опыта работы с Access, но эта ссылка может быть вам полезна:

http://office.microsoft.com/en-us/access/HP052408601033.aspx

«Вы можете разместить всю базу данных Access на сетевом сервере или в общей папке.Это самый простой в реализации метод.Все используют общие данные и используют одни и те же формы, отчеты, запросы, макросы и модули.Используйте эту стратегию, если вы хотите, чтобы все использовали базу данных Access одинаково, или если вы не можете поддерживать пользователей, создающих свои собственные объекты».

«Когда вы открываете файл базы данных Access (.mdb) в общем режиме, Microsoft Access также создает файл информации о блокировке (.ldb) с тем же именем файла (например, Northwind.ldb) и в той же папке, что и файл базы данных. .В этом файле информации о блокировке хранятся имя компьютера (например, mypc) и имя безопасности (например, Admin) каждого общего пользователя базы данных.Microsoft Access использует эту информацию для управления параллелизмом.В большинстве случаев Microsoft Access автоматически удаляет файл с информацией о блокировке, когда последний пользователь закрывает файл базы данных».

Предполагается, что доступ должен быть многопользовательским — я думаю, что Microsoft рекомендует его для 4 или 5 пользователей, но на практике я бы рекомендовал вам никогда не использовать базу данных Access, где есть более одного пользователя, хотя если вы действительно не У меня нет выбора, приемлемо для двоих или троих, с учетом некоторых оговорок.

У меня был опыт работы с четырьмя или пятью системами, использующими серверную часть базы данных Access — все они были получены от других «разработчиков» — и во всех случаях я перемещал их на SQL Server в качестве приоритета после любых необходимых немедленных обновлений и исправлений. при заключении контракта - обычно, как только мне удавалось уговорить начальника оплатить счет.Временной интервал для этого обычно составляет несколько месяцев, поэтому я видел, как он работал одновременно в течение разумного периода времени в нескольких разных приложениях.

На самом деле, как правило, это будет работать достаточно хорошо, если в системе не так много одновременных вставок/обновлений и она не используется интенсивно.Главные практические проблемы, по моему опыту, заключаются в следующем.

  1. Он подвержен коррупции – это просто так.Как правило, это не такая уж большая проблема, поскольку открытие файла и запуск Compact and Repair устранят проблемы, но хороший режим резервного копирования абсолютно необходим.

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

  3. Файл базы данных раздувается из-за того, что Access помечает записи как обновленные или удаленные.Это еще больше замедляет работу системы, поскольку файл приходится загружать по сети.Следовательно, необходим некий режим, который сжимает данные, обычно ежедневно.

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

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

Уже несколько раз говорилось об использовании настоящей многопользовательской бесплатной платформы баз данных.Но одна из причин не названа.Причина в том, сколько существующих, беспорядочных, проблемных, больших баз данных Access начиналось как «несколько записей, максимум один или два пользователя»?Я бы рискнул сказать, что все из них.

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

При использовании общего сетевого ресурса я бы использовал сетевую базу данных (mysql/firebird/mssql) вместо доступа.

Для ситуации, которую вы описываете, использование Access не будет проблемой.

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

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

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

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

Я думаю, вы можете определить это в строке подключения вашего приложения .net.Я погуглил JET, блокировку доступа и записи.

вот связь это может помочь.

Подробную информацию о том, как Access и JET получают данные, см. в принятом ответе.

Пожалуйста, не используйте Access для многопользовательского сценария.

Я только что пережил две недели боли, потому что мой предшественник в проекте выбрал Access в качестве серверной части.

Конкретные причины:

  • Не существует такого понятия, как Linq-to-Access.
  • Access имеет множество особенностей, таких как зависимости от порядка добавления параметров в команды, отладка которых может занять много времени.
  • Доступ не масштабируется
  • Обновления базы данных — рутинная работа по сравнению с использованием SQL Server.
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top