0

根据文章,我刚刚考虑了将评论存储在数据库中的最佳方法,并带有适当的数字。

这个想法是使用复合主键(commentId,articleId)存储评论,其中commentId是根据给定的articleId生成的。生成系统应该和SQL Server中IDENTITY生成列的原理一样,因为如果有人删除了评论,这个数字就再也不会被使用了。我想 Microsoft SQL Server 中没有任何功能可以使用复合 PK 来做到这一点,所以我想问一些替代这个解决方案的方法。

首先想到的是使用事务来获取 MAX(commentId) + 1,但我正在寻找更抽象的东西(可能是 INSTEAD OF 触发器),例如可以在不了解背景的情况下在 LINQ 中使用的东西,只需插入适当的表所有必需的值(所以没有commentId)并保存它。

4

3 回答 3

2

我会为 commentId 使用一个自动生成的标识列,并让它单独作为主键。我会在 articleId 上创建一个索引以进行查找。我还会在插入时使用当前日期自动填充 createdDate 列——在 LINQ 中将其标记为 db 生成和只读,因此它不需要或尝试插入/更新值。要获得编号——如果按日期显示它们还不够——我会按 createdDate 倒数排序,并在选择中使用 Row_Number() 或在客户端编号分配一个数值。

于 2009-02-17T19:20:25.440 回答
1

我会使用标识列作为评论的键,为什么需要对存储在数据库中的评论进行编号?

于 2009-02-17T19:16:53.717 回答
0

感谢您的回复,由于在评论文本中引用,我想要一些带有编号的评论。我不想用名字做出反应,有时一个人反应更多次,所以有了这个系统,我会知道这个人在回复哪一个。

所以今天我做了这个 INSTEAD OF INSERT 触发器:

CREATE TRIGGER InsertComments ON Comments
INSTEAD OF INSERT
AS
DECLARE @Inserted TABLE
(
    ArticleId INT NOT NULL,
    UserId INT NOT NULL,
    CommentDate DATETIME NOT NULL,
    Content NVARCHAR(1000) NOT NULL,
    RowNumber INT NOT NULL
)
INSERT INTO @Inserted
SELECT ArticleId, UserId, CommentDate, Content, ROW_NUMBER() OVER (ORDER BY CommentDate) AS RowNumber
FROM INSERTED
DECLARE @NumberOfRows INT = (SELECT COUNT(*) FROM @Inserted)
DECLARE @i INT = 1
WHILE (@i <= @NumberOfRows)
BEGIN
    SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
    BEGIN TRAN
    DECLARE @CommentId INT = (SELECT ISNULL(MAX(CommentId), 0)
        FROM Comments WHERE ArticleId = (SELECT ArticleId
            FROM @Inserted WHERE RowNumber = @i)) + 1
    INSERT INTO Comments(CommentId, ArticleId, UserId, CommentDate, Content)
    SELECT @CommentId, ArticleId, UserId, CommentDate, Content
    FROM @Inserted WHERE RowNumber = @i
    COMMIT
    SET @i = @i + 1
END

我知道这不是完美的解决方案,但它完全符合我的需要。如果你们中的任何人有一些意见,我会很乐意阅读。

于 2009-02-18T19:12:42.857 回答