Существуют ли проблемы с таблицами, использующими автонумерацию в качестве первичного ключа во внутренней базе данных доступа ms?

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

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

Правильно ли Jet обрабатывает это или есть проблемы с автонумерацией в базе данных FE/BE? Если это маловероятно, но возможно, я уверен, что это все равно будет намного лучше, чем то, с чем сталкиваются мои пользователи в настоящее время, но я хотел бы знать, есть ли способы минимизировать такие проблемы.

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


person owlie    schedule 05.01.2011    source источник


Ответы (4)


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

person Thomas    schedule 05.01.2011
comment
Я согласен с тем, что это абсолютно стандартный подход, никаких известных проблем (с этим...). - person RolandTumble; 05.01.2011

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

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

person Philippe Grondier    schedule 05.01.2011
comment
Э, нет. Идентификаторы репликации плохо работают в Access и приводят к сбою встроенного средства разрешения конфликтов. Нет никаких реальных оснований рекомендовать их здесь вообще. - person David-W-Fenton; 08.01.2011
comment
Сюрприз! Не могли бы вы дать мне несколько ссылок по этому поводу? - person Philippe Grondier; 10.01.2011

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

person David-W-Fenton    schedule 08.01.2011

У меня была та же проблема, тем не менее я применил обходной путь, чтобы получить работу автонумерации из события Onload().

Что я сделал:

  1. Я создаю набор записей на основе Your_Table каждый раз, когда пользователю требуется автонумерация.
  2. Откройте набор записей (первый)
  3. Поиск, если:
    -Ваша_Таблица пуста, затем присваивает значение "1" для поля "Ваше_поле"
    -Ваша_Таблица содержит данные без пропущенных чисел,затем присваивает значение = "Количество строк + 1" в поле Your_field (1,2,....,n+1)
    -В таблице отсутствуют данные (1,3,4,5,7) [Примечание "#2 и # 7 отсутствуют]», затем использует функцию для поиска в Your_Table отсутствующих полей и присвоения Your_Field первого отсутствующего значения (#2 в этом примере)


Private Sub Autonumbering(Your_Table As String)
Dim rst As DAO.Recordset
Dim db As Database

On Error GoTo ErrorHandler

Application.Echo False

Set db = CurrentDb
Set rst = db.OpenRecordset(Your_Table, dbOpenDynaset)

                    With rst
                        .AddNew
                            'Your_Table is Empty, **then** assigns the value "1" to Your_field
                            If DMin("[Your_Field]", Your_Table) = 1 Then
                                'Your_Table is has data without missing numbers,**then** assigns the value = "Count of lines + 1" to Your_field (1,2,....,n+1)
                                If DMax("[Your_Field]", Your_Table) = .RecordCount Then
                                    'Assings n+1 value to [Your_Field] records
                                    Value = .RecordCount + 1
                                        ![Your_Field] = Valor
                                Else
                                    'Your_Table has missing data (1,3,4,5,7) [Note "#2 and #7 are missing]", **then** uses a function to search in Your_Table & _
                     the missing fields and assign to Your_Field the first missing value (#2 in this example)
                                    Value = MyFunction$(Your_Table, "Your_Field")
                                        ![Your_Field] = Value
                                End If
                            Else
                            'Agrega el número 1
                            Value = 1
                            ![Your_Field] = Value
                            End If
                        .Update
                        .Bookmark = .LastModified
                        Me.Requery
                        DoCmd.GoToRecord acDataForm, Me.Name, acGoTo, Value
                        .Move 0, .LastModified
                    End With
ErrorCorregido:
Application.Echo True
Exit Sub

ErrorHandler:
MsgBox "An error ocurred, please verify numbering", vbCritical + vbOKOnly
Resume ErrorCorregido

End Sub


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


Function MyFunction$(cstrTable As String, cstrField As String)

' Read table/query sequentially to record all missing IDs.
' Fill a ListBox to display to found IDs.
' A reference to Microsoft DAO must be present.

  Dim dbs     As DAO.Database
  Dim rst     As DAO.Recordset
  Dim lst     As ListBox
  Dim Col     As Collection

  Dim strSQL  As String
  Dim strList As String
  Dim lngLast As Long
  Dim lngNext As Long
  Dim lngMiss As Long

  ' Build SQL string which sorts the ID field.
  strSQL = "Select " & cstrField & "" _
   & " From " & cstrTable & " Order By 1;"

  Set Col = Nothing
  ' Control to fill with missing numbers.
  'Set lst = Me!lstMissing

  ' Collection to hold the missing IDs.
  Set Col = New Collection

  '// Vacía la colección
  'Erase Col
    ' Read the table.
  Set dbs = CurrentDb
  Set rst = dbs.OpenRecordset(strSQL)

  If rst.RecordCount = 0 Then
    ' The recordset is empty.
    ' Nothing to do.
  Else
    ' Read and save the ID of the first record.
    lngLast = rst(cstrField).value
    rst.MoveNext
    ' Loop from the second record through the recordset
    ' while reading each ID.
    While rst.EOF = False
      lngNext = rst(cstrField).value
      ' For each ID, fill the collection with the
      ' missing IDs between the last ID and this ID.
      For lngMiss = lngLast + 1 To lngNext - 1
        Col.Add (lngMiss)
      Next
      ' Save the last read ID and move on.
      lngLast = lngNext
      rst.MoveNext
    Wend
    ' Finally, add the next possible ID to use.
    Col.Add (lngLast + 1)
  End If
  rst.Close

  For lngMiss = 1 To Col.Count
    ' Build the value list for the ListBox.
    If Len(strList) > 0 Then
      ' Append separator.
      strList = strList & ";"
    End If
    ' Append next item from the collection.
    strList = strList & Col(lngMiss)
    ' For debugging only. May be removed.
    Debug.Print Col(lngMiss)
  Next
  ' Pass the value list to the ListBox.
  ' Doing so will requery it too.
  ' lst.RowSource = strList
  ' For debugging only. May be removed.
  ' Debug.Print strList
  MyFunction$ = Col(1)
  ' Clean up.
  Set rst = Nothing
  Set dbs = Nothing
  Set Col = Nothing
  Set lst = Nothing

End Function
person Adrian Delgado Quesada    schedule 27.10.2015