Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/google-cloud-platform/3.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
如何在mysql中存储类型可以是数字、日期或字符串的数据_Mysql_Sql_Database Design_Entity Attribute Value - Fatal编程技术网

如何在mysql中存储类型可以是数字、日期或字符串的数据

如何在mysql中存储类型可以是数字、日期或字符串的数据,mysql,sql,database-design,entity-attribute-value,Mysql,Sql,Database Design,Entity Attribute Value,我们正在开发一个监控系统。在我们的系统中,值由运行在不同服务器上的代理报告。报告的观察值可以是如下值: 数值。e、 g.“CPU使用率”=55。这意味着55%的CPU处于 使用) 某些事件被触发。e、 g.“备份完成” 状态:例如,SQL Server处于脱机状态 我们希望存储这些观察结果(这些观察结果事先不知道,将在不重新编译的情况下动态添加到系统中) 我们正在考虑将不同的列添加到观察表中,如下所示: IntMeasure -> INTEGER FloatMeasure ->

我们正在开发一个监控系统。在我们的系统中,值由运行在不同服务器上的代理报告。报告的观察值可以是如下值:

  • 数值。e、 g.“CPU使用率”=55。这意味着55%的CPU处于 使用)
  • 某些事件被触发。e、 g.“备份完成”
  • 状态:例如,SQL Server处于脱机状态
我们希望存储这些观察结果(这些观察结果事先不知道,将在不重新编译的情况下动态添加到系统中)

我们正在考虑将不同的列添加到观察表中,如下所示:

IntMeasure -> INTEGER
FloatMeasure -> FLOAT
Status -> varchar(255)
因此,如果我们要存储的值是一个数字,我们可以根据类型使用IntMeasure或FloatMeasure。如果该值是一个status,则可以存储status文本字符串(如果决定添加status(id,name)表,则可以存储status id)


我们认为有可能有一个更正确的设计,但可能会变得缓慢和黑暗,因为连接和动态表名取决于类型?如果我们不能在查询中提前指定表,那么连接将如何工作?

我还没有做过正式的研究,但根据我自己的经验,我猜80%以上的数据库设计缺陷都是由于将性能作为最重要(如果不是唯一)的考虑因素进行设计而产生的

如果一个好的设计需要多个表,请创建多个表。不要自动地认为连接是需要避免的。它们很少是性能问题的真正原因

在数据库设计的所有阶段,首要考虑的是数据完整性。“答案可能并不总是正确的,但我们可以很快给你。”这不是任何商店都应该努力实现的目标。一旦数据完整性被锁定,如果性能成为问题,就可以解决。不要牺牲数据完整性,尤其是为了解决可能不存在的问题

记住这一点,看看你需要什么。您需要存储观察结果。这些观察值在属性的数量和类型上可能有所不同,可以是测量值、事件通知和状态变化等,还可以添加未来观察值的可能性

这似乎符合标准的“类型/子类型”模式,“观察”条目为类型,每种类型或种类的观察为子类型,并建议某种形式的类型指示器字段,例如:

create table Observations(
   ...,
   ObservationKind  char( 1 ) check( ObservationKind in( 'M', 'E', 'S' )),
   ...
);
但是,在检查约束中硬编码这样的列表具有非常低的可维护性级别。它成为模式的一部分,只能使用DDL语句进行更改。这不是您的DBA所期待的

因此,在他们自己的查找表中有各种观察结果:

ID  Name         Meaning
==  ===========  =======
M   Measurement  The value of some system metric (CPU_Usage).
E   Event        An event has been detected.
S   Status       A change in a status has been detected.
(char字段也可以是int或smallint。我在这里使用char进行说明。)

然后用PK和所有观察共有的属性填写观察表

create table Observations(
   ID               int identity primary key,
   ObservationKind  char( 1 ) not null,
   DateEntered      date not null,
   ...,
   constraint FK_ObservationKind foreign key( ObservationKind )
      references ObservationKinds( ID ),
   constraint UQ_ObservationIDKind( ID, ObservationKind )
);
在Kind字段和PK的组合上创建一个唯一的索引似乎有些奇怪,它本身就是唯一的,但请耐心等待

现在,每种类型或子类型都有自己的表。请注意,每种观察都会得到一个表,而不是数据类型

create table Measurements(
    ID                   int not null,
    ObservationKind      char( 1 ) check( ObservationKind = 'M' ),
    Name                 varchar( 32 ) not null, -- Such as "CPU Usage"
    Value                double not null, -- such as 55.00
    ...,  -- other attributes of Measurement observations
    constraint PK_Measurements primary key( ID, ObservationKind ),
    constraint FK_Measurements_Observations foreign key( ID, ObservationKind )
        references Observations( ID, ObservationKind )
);
对于其他类型的观察,前两个字段将是相同的,但检查约束将强制将值设置为适当的类型。其他字段的编号、名称和数据类型可能不同

create table Measurements(
    ID                   int not null,
    ObservationKind      char( 1 ) check( ObservationKind = 'M' ),
    Name                 varchar( 32 ) not null, -- Such as "CPU Usage"
    Value                double not null, -- such as 55.00
    ...,  -- other attributes of Measurement observations
    constraint PK_Measurements primary key( ID, ObservationKind ),
    constraint FK_Measurements_Observations foreign key( ID, ObservationKind )
        references Observations( ID, ObservationKind )
);
让我们检查一下度量表中可能存在的一个示例元组:

ID    ObservationKind  Name       Value  ...
====  ===============  =========  =====
1001  M                CPU Usage  55.0   ...
为了使此元组在此表中存在,必须首先在观测表中存在ID值为1001、观测种类值为“M”的匹配项。观察表或测量表中不能存在ID值为1001的其他条目,也不能存在于任何其他“种类”表(事件、状态)中。这对所有类型的表都是一样的

我还建议为每种观察创建一个视图,该视图将提供每种类型与主观察表的连接:

create view MeasurementObservations as
    select ...
    from   Observations o
    join   Measurements m
        on m.ID = o.ID;
任何只与度量一起工作的代码只需要点击这个视图,而不需要点击底层表。使用视图在应用程序代码和原始数据之间创建一道抽象墙,极大地提高了数据库的可维护性

现在,创建另一种类型的观察,例如“Error”,需要在ObservationKinds表中插入一条简单语句:

F   Fault        A fault or error has been detected.

当然,您需要为这些错误观察创建一个新的表和视图,但这样做不会对现有的表、视图或应用程序代码产生影响(当然,编写新代码以处理新观察除外)。

只需将其创建为VARCHAR即可

这将允许您在其中存储所需的任何数据。根据字段中的数字进行查询要困难得多,例如

Select * from table where MyVARCHARField > 50 //get CPU > 50
但是,如果您认为需要这样做,那么您需要为每个项指定一个字段或一个通用表,例如

Create Table

Description : Varchar
ValueType : Varchar //Can be String, Float, Int
ValueString: Varchar
ValueFloat: Float
ValueInt : Int
然后,当您填写数据时,您可以将您的值放入正确的字段中,然后像这样选择

Select Description ,ValueInt from table where Description like '%cpu%' and ValueInt > 50

我用了两列来解决类似的问题。第一列是数据类型,第二个值包含作为Varchar的数据

第一列有代码(例如1=整数、2=字符串、3=日期等),可以组合起来比较值。(例如,在type=1时查找最大整数)


我没有连接,但我认为您可以使用这种方法。如果明天引入更多的数据类型,它也会对您有所帮助。

“这是一个好的选择吗?”-这取决于几个因素……列总是具有相同的类型,而不管其中存储了什么。无论如何,价值观本身都不应该“可能”结合起来。要确定特定设计是否合适,首先需要知道如何使用/查询数据。还有,像t这样的设计