Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 应用程序配置或应用程序选项设置的最佳表格设计?_Sql_Database_Database Design - Fatal编程技术网

Sql 应用程序配置或应用程序选项设置的最佳表格设计?

Sql 应用程序配置或应用程序选项设置的最佳表格设计?,sql,database,database-design,Sql,Database,Database Design,我需要在数据库中存储一系列配置值。 我想到的存储它们的两种方法是:一个表有两列(名称、值),每对一行,或者一个表有一列,每一个配置参数和一行? 对于第一个,我只需要添加另一行来添加配置值,对于第二个,我需要向表中添加一列。我应该考虑其中任何一个问题吗?一个比另一个更有效率吗 我认为2列(名称、值)设计更好。如前所述,如果需要添加新属性,则只需“插入”新行即可。在另一种设计(单行)中,您需要更改表架构以为新属性添加列 但是,这取决于您的属性列表将来是否会更改 CREATE TABLE Config

我需要在数据库中存储一系列配置值。 我想到的存储它们的两种方法是:一个表有两列(名称、值),每对一行,或者一个表有一列,每一个配置参数和一行? 对于第一个,我只需要添加另一行来添加配置值,对于第二个,我需要向表中添加一列。我应该考虑其中任何一个问题吗?一个比另一个更有效率吗

我认为2列(名称、值)设计更好。如前所述,如果需要添加新属性,则只需“
插入
”新行即可。在另一种设计(单行)中,您需要更改表架构以为新属性添加列

但是,这取决于您的属性列表将来是否会更改

CREATE TABLE Configuration (
    Name ...,
    Value ...,
);
最好的办法。向表中添加一列通常很糟糕,而一个只有一行的表又有什么意义呢


不确定这是否适合SQL,但唉……问题回答。

你应该考虑的第一个问题是:停止思考检索信息的效率。首先也是最重要的是,找出如何有效和正确地对数据建模,然后(并且只有在那时)找出如何有效地进行建模

因此,这取决于您存储的配置数据的性质。如果单独的(名称、值)对基本上不相关,则将其存储为每行一个。如果它们是相关的,那么您可能需要考虑具有多个列的方案。

我说的相关是什么意思?考虑一些缓存配置。每个缓存都有几个属性:

  • 驱逐政策
  • 有效期
  • 最大尺寸
假设每个缓存都有一个名称。您可以将此数据存储为三行:

  • \u驱逐
  • \u到期日
  • \u最大尺寸
但是这些数据是相关的,您可能经常需要一次检索所有这些数据。在这种情况下,有一个包含五列的cache\u config表是有意义的:id、name、逐出、过期、max\u size


这就是我所说的相关数据。

我两种方法都用过,我更喜欢两列法。返回到每个配置的“新建”列的原因是,您需要更改代码以添加新设置

我更喜欢使用每设置一列的方法(当我访问值时)。这是因为配置设置更明确。但这种偏好并没有超过向表中添加新配置的难度


我建议使用2列方法。然后设置一个访问器函数/存储过程来获取这些值。

还有一个需要考虑的问题:每个配置参数都有一列,您可以很容易地获得版本。每行代表一个版本*



*对于配置数据的完整参数集(如a中指出的),我将使用键/值结构,每个配置条目有一行。您可能会读取此数据一次并缓存它,因此性能不是问题。正如您所指出的,每次更改配置键集时添加列需要更多的维护

SQL擅长建模和操作任意大的相似(如果不是相同的)结构化数据集。一组配置信息实际上并不是这样——您有一行数据,或者有多行完全不相关的数据。也就是说,您只是将其用作数据存储。我建议跳过SQL数据模型,简单点。

视情况而定

如果你有少于15个值,我会为每个值做一列

如果你定期改变设置的数量,或者如果你经常不使用所有的设置,我会考虑每次设置一个行。< /P> 除此之外,它可能是一个tossup。取决于您的使用模式。如果您总是需要获取所有设置,那么将它们放在一行可能是最快的


添加列并不太难,而且如果编程合理,通常不必更新任何其他代码。

您可以使用XML高效地保存配置。一些数据库支持纯XML特性,您可以将值保存为XML数据类型,并且可以在该特定列上运行XQUERY

创建一个具有两个列名和配置的表。使用字符串数据类型命名,使用xml数据类型配置,因此无需担心插入和删除新的配置参数,只需使用xml中的新标记即可。若数据库不支持XML,那个么只需将其保存为一个字符串,但采用XML格式,这样您就可以手动或使用一些API高效地解析该配置

我认为这是一种更好的方法,而不是将完整的配置存储为字符串

我在这里写了一篇关于我们 性能不是问题,因为它在应用程序启动时只被拉一次,并存储在字典中以便于查找


不确定您的应用程序,但我们这样做的重要原因是,如果您在开发、测试等中,现在就不可能使用生产值。

为每个(应用程序)配置设置(或应用程序选项)使用单独的行的一个缺点就是不能将设置值存储在具有适当数据类型的列中。用户可以输入无效类型的数据吗?这与你的申请有关吗

使用单独列的一个好处是,数据库中的任何代码(例如存储过程、函数等)都可以使用适当数据类型的值,而无需先检查无效值,然后再转换为适当的数据类型

如果您手动部署对应用程序数据库的更改,那么是的,如果您使用的是EAV设计,部署新的配置设置会稍微容易一些,但真正节省的是什么:

INSERT Options ( ConfigurationSetting, Value )
VALUES ( 'NewConfigurationSetting', NewConfigurationSettingValue )
与:

ALTER TABLE Options ADD NewConfigurationSetting some_datatype

UPDATE Options
SET NewConfigurationSetting = NewConfigurationSettingValue

我鄙视将非字符串值放在字符串列中(aka,不正确)-
CREATE TABLE [dbo].[SystemSetting](
    [SystemSettingId] [int] IDENTITY NOT NULL,

    [SettingKeyName] [nvarchar](64) NOT NULL, 
    [SettingDataType] [nvarchar](64) NOT NULL, /* store the datatype as string here */

    [SettingValueBigInt] bigint NULL, 
    [SettingValueNumeric] numeric NULL, 
    [SettingValueSmallInt] smallint NULL, 
    [SettingValueDecimal] decimal NULL, 
    [SettingValueSmallMoney] smallmoney NULL, 
    [SettingValueInt] int NULL, 
    [SettingValueTinyInt] tinyint NULL, 
    [SettingValueMoney] money NULL, 
    [SettingValueFloat] float NULL, 
    [SettingValueReal] real NULL, 
    [SettingValueDate] date NULL, 
    [SettingValueDateTimeOffSet] datetimeoffset NULL, 
    [SettingValueDateTime2] datetime2 NULL, 
    [SettingValueSmallDateTime] smalldatetime NULL, 
    [SettingValueDateTime] datetime NULL, 
    [SettingValueTime] time NULL, 
    [SettingValueVarChar] varchar(1024) NULL, 
    [SettingValueChar] char NULL, 

    [InsertDate] [datetime] NOT NULL DEFAULT (GETDATE()),               
    [InsertedBy] [nvarchar](50) NOT NULL DEFAULT (SUSER_SNAME()),       
    [LastUpdated] [datetime] NOT NULL DEFAULT (GETDATE()),              
    [LastUpdatedBy] [nvarchar](50) NOT NULL DEFAULT (SUSER_SNAME()),    
)
DROP TABLE [dbo].[SystemSetting]
DROP TABLE [dbo].[SystemSettingCategory]

CREATE TABLE [dbo].[SystemSettingCategory] (
    [SystemSettingCategoryId] [int] NOT NULL,
    [SystemSettingCategoryName] [nvarchar](64) NOT NULL, 
    [InsertDate] [datetime] NOT NULL DEFAULT (GETDATE()),               
    [InsertedBy] [nvarchar](50) NOT NULL DEFAULT (SUSER_SNAME()),       
    [LastUpdated] [datetime] NOT NULL DEFAULT (GETDATE()),              
    [LastUpdatedBy] [nvarchar](50) NOT NULL DEFAULT (SUSER_SNAME()),    
    CONSTRAINT [PK_SystemSettingCategory] PRIMARY KEY CLUSTERED ([SystemSettingCategoryId] ASC),
    CONSTRAINT UQ_SystemSettingCategoryName UNIQUE NONCLUSTERED ([SystemSettingCategoryName])
)   




CREATE TABLE [dbo].[SystemSetting] (
    [SystemSettingId] [int] NOT NULL,
    [SystemSettingCategoryId] INT NOT NULL,     /* FK to [SystemSettingCategory], not shown here */
    [SettingKeyName] [nvarchar](64) NOT NULL, 
    [SettingValue] nvarchar(1024) NULL,
    [InsertDate] [datetime] NOT NULL DEFAULT (GETDATE()),               
    [InsertedBy] [nvarchar](50) NOT NULL DEFAULT (SUSER_SNAME()),       
    [LastUpdated] [datetime] NOT NULL DEFAULT (GETDATE()),              
    [LastUpdatedBy] [nvarchar](50) NOT NULL DEFAULT (SUSER_SNAME()),    
    CONSTRAINT [PK_SystemSetting] PRIMARY KEY CLUSTERED ([SystemSettingId] ASC),
    CONSTRAINT FK_SystemSettingCategory_SystemSettingCategoryId foreign key ([SystemSettingCategoryId]) references [SystemSettingCategory] ([SystemSettingCategoryId]),
    CONSTRAINT UQ_SystemSettingCategoryId_SettingKeyName UNIQUE NONCLUSTERED ( [SystemSettingCategoryId] , [SettingKeyName] )
)   



INSERT INTO [dbo].[SystemSettingCategory] ( [SystemSettingCategoryId] , [SystemSettingCategoryName] )
select 101 , 'EmployeeSettings' UNION ALL select 201, 'StopLightSettings'

INSERT INTO [dbo].[SystemSetting] ( [SystemSettingId] , [SystemSettingCategoryId] , [SettingKeyName] , [SettingValue] )
          select 1001 , 101 , 'MininumAgeRequirementMonths' , convert(varchar(16) , (12 * 18))
UNION ALL select 1002 , 101 , 'MininumExperienceMonths' , convert(varchar(8) , 24)
UNION ALL select 2001 , 201 , 'RedLightPosition' , 'top'
UNION ALL select 2002 , 201 , 'YellowLightPosition' , 'middle'
UNION ALL select 2003 , 201 , 'GreenLightPosition' , 'bottom'

/* should fail */
/* start 
INSERT INTO [dbo].[SystemSettingCategory] ( [SystemSettingCategoryId] , [SystemSettingCategoryName] )
select 3333 , 'EmployeeSettings'
INSERT INTO [dbo].[SystemSettingCategory] ( [SystemSettingCategoryId] , [SystemSettingCategoryName] )
select 101 , 'xxxxxxxxxxxxxx'
INSERT INTO [dbo].[SystemSetting] ( [SystemSettingId] , [SystemSettingCategoryId] , [SettingKeyName] , [SettingValue] )
          select 5555 , 101 , 'MininumAgeRequirementMonths' , 555
INSERT INTO [dbo].[SystemSetting] ( [SystemSettingId] , [SystemSettingCategoryId] , [SettingKeyName] , [SettingValue] )
          select 1001 , 101 , 'yyyyyyyyyyyyyy' , 777
INSERT INTO [dbo].[SystemSetting] ( [SystemSettingId] , [SystemSettingCategoryId] , [SettingKeyName] , [SettingValue] )
          select 5555 , 555 , 'Bad FK' , 555
 end */


Select * from [dbo].[SystemSetting] where [SystemSettingCategoryId] = 101 /* employee related */
Select * from [dbo].[SystemSetting] where [SystemSettingCategoryId] = 201 /* StopLightSettings related */
public class EmployeeSettings
{
    public Int16 MininumAgeRequirementMonths { get; set; }
    public Int16 MininumExperienceMonths{ get; set; }
}


public class StopLightSettings
{
    public string RedLightPosition { get; set; }
    public string YellowLightPosition { get; set; }
    public string GreenLightPosition { get; set; }
}
ID client_id valid_from     valid_until configuration_file
-------------------------------------------------------
1         1   2016/03/16         NULL      <<DOCUMENT>>