当前位置: 首页 > 面试题库 >

性能考虑:将行分散在多个表中,而将所有行集中在一个表中

刘运浩
2023-03-14
问题内容

性能考虑:将行分散在多个表中,而将所有行集中在一个表中。

你好。

我需要在SQL DB中记录有关应用程序中正在进行的每个步骤的信息。有某些表,我希望日志与之相关:产品-创建产品更改时应记录的日志等。订单-与上述相同-
发货等-等等,等等。

数据将需要经常检索。

我对如何做到这一点几乎没有想法:

  1. 有一个包含所有这些表的列的日志表,然后当我想在某个产品的UI中表示数据时,请从Log中选择*,其中LogId = Product.ProductId。我知道拥有很多列可能会很有趣,但是我有这样的感觉,那就是性能会更好。另一方面,此表中将有大量行。
  2. 每个日志类型(ProductLogs,OrderLogs等)都有很多日志表,我真的不喜欢这个想法,因为它不一致,并且有许多结构相同的表没有意义,但是(?)搜索时可能更快在行数较少的表中(可能是错误的吗?)。
  3. 根据声明号。1,我可以做第二个多对一表,该表将具有LogId,TableNameId和RowId cols,并将一个日志行引用到数据库中的许多表行,而不是使用UDF来检索数据(例如,日志ID 234属于CustomerId 345上的Customer表和ProductId = RowId的Product表);我认为这是最好的方法,但是同样,可能会有大量的行,这会减慢搜索速度吗?或者这是应该怎么做的,Whatcha说?

上面列表中的3号示例:

CREATE TABLE [dbo].[Log](
    [LogId] [int] IDENTITY(1,1) NOT NULL,
    [UserId] [int] NULL,
    [Description] [varchar](1024) NOT NULL,
 CONSTRAINT [PK_Log] PRIMARY KEY CLUSTERED 
(
    [LogId] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO
ALTER TABLE [dbo].[Log]  WITH CHECK ADD  CONSTRAINT [FK_Log_Table] FOREIGN KEY([UserId])
REFERENCES [dbo].[Table] ([TableId])
GO
ALTER TABLE [dbo].[Log] CHECK CONSTRAINT [FK_Log_Table]
---------------------------------------------------------------------
CREATE TABLE [dbo].[LogReference](
    [LogId] [int] NOT NULL,
    [TableName] [varchar](32) NOT NULL,
    [RowId] [int] NOT NULL,
 CONSTRAINT [PK_LogReference] PRIMARY KEY CLUSTERED 
(
    [LogId] ASC,
    [TableName] ASC,
    [RowId] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO
SET ANSI_PADDING OFF
GO
ALTER TABLE [dbo].[LogReference]  WITH CHECK ADD  CONSTRAINT [FK_LogReference_Log] FOREIGN KEY([LogId])
REFERENCES [dbo].[Log] ([LogId])
GO
ALTER TABLE [dbo].[LogReference] CHECK CONSTRAINT [FK_LogReference_Log]
---------------------------------------------------------------------
CREATE FUNCTION GetLog
(   
    @TableName varchar(32),
    @RowId int
)
RETURNS 
@Log TABLE
(       
    LogId int not null,
    UserId int not null,
    Description varchar(1024) not null
)
AS
BEGIN

INSERT INTO @Log
SELECT     [Log].LogId, [Log].UserId, [Log].Description
FROM         [Log] INNER JOIN
                      LogReference ON [Log].LogId = LogReference.LogId
WHERE     (LogReference.TableName = @TableName) AND (LogReference.RowId = @RowId)
    RETURN 
END
GO

问题答案:

由于以下几个原因,我肯定会选择选项3:

数据应位于表的字段中,而不是表名(选项2)或字段名(选项1)。这样,数据库变得更易于使用和维护。

通常,窄表的性能更好。行数对性能的影响小于字段数。

如果每个表都有一个字段(选项1),则当只有少数几个表受某个操作影响时,您可能会得到很多空字段。



 类似资料:
  • 问题内容: 我有两个具有相同结构的表。我需要从一个表中选择数据,然后将它们存储到另一个表中。 我怎样才能做到这一点? 问题答案: 因为它们是相同的结构,所以您可以做

  • 问题内容: 我怎样才能通过mysql仅在一行中加入多行? 例子 : 学生表 现在我想要这种格式 我不确定该怎么做?我应该创建视图还是表格? 我想一个观点会很好。 问题答案: 我同意其他答案,即与PHP一起使用逗号分隔的值进行拆分可能是最好的方法,但是,如果由于任何其他原因需要通过Pure SQL建议的输出,则建议使用以下方法之一。 1.自我加入 2.使用ROW_NUMBER类型函数进行汇总

  • 问题内容: 我有一个关于SQL-select-query的问题:该表包含几列,其中一列是一个名为“ size”的整数列- 我要执行的任务是查询表以获取所有总和行(它们的值),或更确切地说,在我的ResultSet中获得一个称为“ overallSize”的人工列,其中包含表中所有“大小”值的总和。最好使用WHERE子句仅添加某些值(“ WHERE bla = 5”或类似的值)。 数据库引擎是HSQ

  • 问题内容: 如何将一个表中的一行连接到具有另一表上给定列的MAX值的行? 例如,我有一张桌子和一张桌子。我想以表中该拍卖的最高出价(即列AND的最高值,其中= )加入拍卖表。 问题答案: 这很烦人。您最好在每个获胜的Auction_bid中都带有一个“优胜者”标志。 请注意,竞标价为零的竞标价将根本不会列出,而有关联的竞标(会发生这种情况)将为每个并列竞标出现一次。

  • 问题内容: 我有一个字符串变量,有可能值,和。 我想使用if语句将所有这些值进行比较(大小写相等),例如: 有没有一种方法可以避免使用多个OR(||)运算符并在一个表达式中比较值?例如,像这样: 问题答案: 我找到了更好的解决方案。这可以通过RegEx实现: 对于不区分大小写的匹配:

  • 问题内容: 我有一个带有user_ids的表,另一个带有user_ids和其他数据(空)的表。 我想将所有ID插入空表。 我知道我可以用php脚本甚至用以下命令创建copy \ paste脚本 我感兴趣的是,当我不提及每个值时,我能以某种方式使用sql创建查询吗?更像是将所有选定的值复制到新表中。喜欢 问题答案: 看看st INSERT … SELECT语法 使用INSERT … SELECT,您