Какая платформа ORM может лучше всего обработать проектирование баз данных MVCC?

Решение, которое я нашел, это указать громкость для каждого трека в порядке «потомка» и затем не использовать фильтр нормализации.

Я использую этот пример, где я объединяю один и тот же аудиофайл в разных положениях:

ffmpeg -vn -i test.mp3 -i test.mp3 -i test.mp3 -filter_complex "[0]adelay=0|0,volume=3[a];[1]adelay=2000|2000,volume=2[b];[2]adelay=4000|4000,volume=1[c];[a][b][c]amix=inputs=3:dropout_transition=0" -q:a 1 -acodec libmp3lame -y amix-volume.mp3

Подробнее см. это изображение. Первый трек - обычное микширование, второе - с указанными томами; третий - оригинальный трек. Как мы видим, 2-й трек выглядит нормально.

ffmpeg -vn -i test.mp3 -i test.mp3 -i test.mp3 -filter_complex "[0]adelay=0|0[a];[1]adelay=2000|2000[b];[2]adelay=4000|4000[c];[a][b][c]amix=inputs=3:dropout_transition=0" -q:a 1 -acodec libmp3lame -y amix-no-volume.mp3

ffmpeg -vn -i test.mp3 -i test.mp3 -i test.mp3 -filter_complex "[0]adelay=0|0,volume=3[a];[1]adelay=2000|2000,volume=2[b];[2]adelay=4000|4000,volume=1[c];[a][b][c]amix=inputs=3:dropout_transition=0" -q:a 1 -acodec libmp3lame -y amix-volume.mp3

Я не могу понять, почему amix изменяет громкость; так или иначе; Я долгое время рылся за хорошим решением.

9
задан Eric Z Beard 5 September 2008 в 19:37
поделиться

6 ответов

Я мог бы полагать, что реализация уровня MVCC просто в DB, с помощью сохранила procs и представления для обработки моих операций данных. Затем Вы могли представить разумный API любому ORM, который был способен к отображению на и от сохраненного procs, и Вы могли позволить DB иметь дело с проблемами целостности данных (так как это - в значительной степени сборка для этого). Если бы Вы пошли этим путем, то Вы могли бы хотеть посмотреть на более чистое решение для Отображения как IBatis или IBatis.net.

3
ответ дан 4 December 2019 в 22:31
поделиться

Я всегда полагал, что Вы будете использовать дб, включают обновление и удаляют для выставления тех строк в таблицу TableName_Audit.

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

0
ответ дан 4 December 2019 в 22:31
поделиться

Насколько я знаю платформы ORM собираются хотеть сгенерировать код CRUD для Вас, таким образом, они должны были бы быть явно разработаны для реализации опции MVCC; я не знаю ни о ком, которые делают так из поля.

С точки зрения платформы Объекта CSLA не реализует персистентность для Вас вообще - это просто определяет интерфейс "Data Adapter", который Вы используете для реализации безотносительно персистентности, в которой Вы нуждаетесь. Таким образом, Вы могли настроить генерацию кода (CodeSmith, и т.д.) шаблоны, чтобы автоматически сгенерировать логику CRUD для Ваших объектов CSLA, которые соглашаются с архитектурой базы данных MVCC.

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

1
ответ дан 4 December 2019 в 22:31
поделиться

Я разработал базу данных так же (только ВСТАВЛЯЕТ — никакие ОБНОВЛЕНИЯ, нет УДАЛЯЕТ).

Почти все мои Запросы Select были против представлений только текущих строк для каждой таблицы (самое большое количество пересмотра).

Представления были похожи на этот …

SELECT
    dbo.tblBook.BookId,
    dbo.tblBook.RevisionId,
    dbo.tblBook.Title,
    dbo.tblBook.AuthorId,
    dbo.tblBook.Price,
    dbo.tblBook.Deleted
FROM
    dbo.tblBook INNER JOIN
    (
        SELECT
            BookId,
            MAX(RevisionId) AS RevisionId
        FROM
            dbo.tblBook
        GROUP BY
            BookId
    ) AS CurrentBookRevision ON
    dbo.tblBook.BookId = CurrentBookRevision.BookId AND
    dbo.tblBook.RevisionId = CurrentBookRevision.RevisionId
WHERE
    dbo.tblBook.Deleted = 0

И мои вставки (и обновления и удаляет) были все обработаны хранимыми процедурами (один на таблицу).

Хранимые процедуры были похожи на этот …

ALTER procedure [dbo].[sp_Book_CreateUpdateDelete]
    @BookId      uniqueidentifier,
    @RevisionId  bigint,
    @Title       varchar(256),
    @AuthorId    uniqueidentifier,
    @Price       smallmoney,
    @Deleted     bit
as
    insert into tblBook
        (
            BookId,
            RevisionId,
            Title,
            AuthorId,
            Price,
            Deleted
        )
    values
        (
            @BookId,
            @RevisionId,
            @Title,
            @AuthorId,
            @Price,
            @Deleted
        )

Числа пересмотра были обработаны на транзакцию в … кода Visual Basic

Shared Sub Save(ByVal UserId As Guid, ByVal Explanation As String, ByVal Commands As Collections.Generic.Queue(Of SqlCommand))
    Dim Connection As SqlConnection = New SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings("Connection").ConnectionString)
    Connection.Open()
    Dim Transaction As SqlTransaction = Connection.BeginTransaction
    Try
        Dim RevisionId As Integer = Nothing
        Dim RevisionCommand As SqlCommand = New SqlCommand("sp_Revision_Create", Connection)
        RevisionCommand.CommandType = CommandType.StoredProcedure
        RevisionCommand.Parameters.AddWithValue("@RevisionId", 0)
        RevisionCommand.Parameters(0).SqlDbType = SqlDbType.BigInt
        RevisionCommand.Parameters(0).Direction = ParameterDirection.Output
        RevisionCommand.Parameters.AddWithValue("@UserId", UserId)
        RevisionCommand.Parameters.AddWithValue("@Explanation", Explanation)
        RevisionCommand.Transaction = Transaction
        LogDatabaseActivity(RevisionCommand)
        If RevisionCommand.ExecuteNonQuery() = 1 Then 'rows inserted
            RevisionId = CInt(RevisionCommand.Parameters(0).Value) 'generated key
        Else
            Throw New Exception("Zero rows affected.")
        End If
        For Each Command As SqlCommand In Commands
            Command.Connection = Connection
            Command.Transaction = Transaction
            Command.CommandType = CommandType.StoredProcedure
            Command.Parameters.AddWithValue("@RevisionId", RevisionId)
            LogDatabaseActivity(Command)
            If Command.ExecuteNonQuery() < 1 Then 'rows inserted
                Throw New Exception("Zero rows affected.")
            End If
        Next
        Transaction.Commit()
    Catch ex As Exception
        Transaction.Rollback()
        Throw New Exception("Rolled back transaction", ex)
    Finally
        Connection.Close()
    End Try
End Sub

Я создал объект для каждой таблицы, каждого с конструкторами, свойствами экземпляра и методами, create-update-delete команды, набор функций средства поиска и IComparable сортирующие функции. Это был огромный объем кода.

Непосредственная Таблица базы данных к объекту VB...

Public Class Book
    Implements iComparable

#Region " Constructors "

    Private _BookId As Guid
    Private _RevisionId As Integer
    Private _Title As String
    Private _AuthorId As Guid
    Private _Price As Decimal
    Private _Deleted As Boolean

    ...

    Sub New(ByVal BookRow As DataRow)
        Try
            _BookId = New Guid(BookRow("BookId").ToString)
            _RevisionId = CInt(BookRow("RevisionId"))
            _Title = CStr(BookRow("Title"))
            _AuthorId = New Guid(BookRow("AuthorId").ToString)
            _Price = CDec(BookRow("Price"))
        Catch ex As Exception
            'TO DO: log exception
            Throw New Exception("DataRow does not contain valid Book data.", ex)
        End Try
    End Sub

#End Region

...

#Region " Create, Update & Delete "

    Function Save() As SqlCommand
        If _BookId = Guid.Empty Then
            _BookId = Guid.NewGuid()
        End If
        Dim Command As SqlCommand = New SqlCommand("sp_Book_CreateUpdateDelete")
        Command.Parameters.AddWithValue("@BookId", _BookId)
        Command.Parameters.AddWithValue("@Title", _Title)
        Command.Parameters.AddWithValue("@AuthorId", _AuthorId)
        Command.Parameters.AddWithValue("@Price", _Price)
        Command.Parameters.AddWithValue("@Deleted", _Deleted)
        Return Command
    End Function

    Shared Function Delete(ByVal BookId As Guid) As SqlCommand
        Dim Doomed As Book = FindByBookId(BookId)
        Doomed.Deleted = True
        Return Doomed.Save()
    End Function

    ...

#End Region

...

#Region " Finders "

    Shared Function FindByBookId(ByVal BookId As Guid, Optional ByVal TryDeleted As Boolean = False) As Book
        Dim Command As SqlCommand
        If TryDeleted Then
            Command = New SqlCommand("sp_Book_FindByBookIdTryDeleted")
        Else
            Command = New SqlCommand("sp_Book_FindByBookId")
        End If
        Command.Parameters.AddWithValue("@BookId", BookId)
        If Database.Find(Command).Rows.Count > 0 Then
            Return New Book(Database.Find(Command).Rows(0))
        Else
            Return Nothing
        End If
    End Function

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

ПРОФЕССИОНАЛЫ:

  • Общая история сохраняется
  • Меньше хранимых процедур

НЕДОСТАТКИ:

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

ЗАКЛЮЧЕНИЕ:

  • Я не перешел бы к такой проблеме на новом проекте без некоторого простого в использовании out-of-the-box ORM решение.

Мне любопытно, если Microsoft Entity Framework может обработать такие проектирования баз данных хорошо.

Jeff и остальная часть, которая команда Переполнения стека должна была заниматься подобными проблемами при разработке Переполнения стека: Прошлые изменения отредактированных вопросов и ответов сохраняются и восстановимы.

Я полагаю, что Jeff заявил, что его команда привыкла Linq для SQL Server MS и SQL.

Интересно, как они обработали эти проблемы.

3
ответ дан 4 December 2019 в 22:31
поделиться

То, что мы делаем, является просто использованием, нормальный ORM (в спящем режиме) и обрабатывает MVCC с представлениями + вместо триггеров.

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

Нет.. Я ненавижу этот метод :) Я пошел бы с хранимой процедурой API, как предложил Tim.

0
ответ дан 4 December 2019 в 22:31
поделиться

Проверьте проект Envers - работы, любезные с приложениями JPA/Hibernate, и в основном делает это для Вас - отслеживает различные версии каждого Объекта в другой таблице и дает Вам подобные SVN возможности ("Дай мне версию Человека, используемого 05.11.2008...")

http://www.jboss.org/envers/

/Jens

1
ответ дан 4 December 2019 в 22:31
поделиться
Другие вопросы по тегам:

Похожие вопросы: