如何在mysql中存储类型可以是数字,日期或字符串的数据
技术问答
420 人阅读
|
0 人回复
|
2023-09-12
|
我们正在开发一个监控系统。在我们的系统中,值是由运行在不同服务器上的代理报告。报告的观察结果如下:
6 n# I. r- m% S例如, CPU使用率” =表示正在使用555。%的CPU)。* h2 d4 ]0 D1 b4 u
某些事件被解雇了。例如“备份完成”。& L7 \& W5 `, N* Q% |* H) l
状态:例如,SQL Server脱机。我们需要存储这些观测值(这些观测值是未知的,动态地添加到系统中而不需要重新编译)。
+ T3 e$ J" ^6 e; K我们正在考虑在观察表中添加不同的列,如下所示:, I7 e- g+ u9 @: h9 j) R
IntMeasure -> INTEGERFloatMeasure -> FLOATStatus -> varchar(255)因此,如果我们希望存储值是一个数字,则可以根据类型使用IntMeasure或FloatMeasure。如果值处于状态,则可以存储状态字符串(如果决定添加)Statuses(id,name)表,可以存储状态id)。
! T0 _" O- K9 C' } t; L我们认为可能有一个更正确的设计,但由于连接和动态表名称(取决于类型)而可能变得缓慢而黑暗。如果我们无法在查询中提前指定表,联接将如何工作?5 ^3 Q8 S A |1 @
% ?4 \( T5 [/ c. Q- W- T: Z
解决方案: + }7 H5 w) p7 Q `" L. k7 e4 c
我还没有做过正式的研究,但根据我自己的经验,我猜超过80个%由性能(最重要的考虑因素)引起的数据库设计缺陷。
5 G6 Q! X& G% P* c如果一个好的设计需要多个表,创建多个表。不要自动假设避免添加连接。它们很少是性能问题的真正原因。9 V& e% @" T: k0 s9 e
在数据库设计的所有阶段,首先要考虑的因素是数据完整性。答案可能并不总是正确的,但我们可以很快为您提供它。一旦数据完整性被锁定, K) o* ~+ s) v+ s @
若性能成为问题 ,可以解决。不要牺牲数据的完整性,特别是解决可能不存在的问题。
) U; [2 D5 t2 `: P: u8 R1 l! g考虑到这一点,请看看你需要什么。您有需要存储的观察值。这些观察值可以不同于属性的数量和类型,可以是测量值、事件通知和状态变化,也可以添加未来的观察值。1 d: s4 c# {5 t; k" j2 q
这似乎适用于标准的类型/子类型模式,其中观察项目为类型,每个观察值或类型为子类型,并建议某种形式的类型指示符字段,如:
7 J+ @) z( m8 Q% V7 screate table Observations( ..., ObservationKind char( 1 ) check( ObservationKind in( 'M','E','S ), ...);然而,在检查约束中对此类列表进行硬编码具有非常低的可维护性水平。它成为架构的一部分,只能使用DDL更改句子DBA不会期待的。- n- ? y8 p. E9 V2 }. ]0 X
因此,在自己的搜索表中有各种观察结果:% m; M7 t1 [: K
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解释。
( G( A* |4 {: Z' G! A8 W" f然后用PK填写与所有观察共同属性的观察表。
! N! |9 ~0 h# I/ Q9 \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在组合上创造唯一的索引似乎很奇怪,这本身就是唯一的,但请耐心等待。
; e% L, u# ` h: }; ?2 S) Z现在,每种类型或子类型都有自己的表。请注意,每种观察都得到一个表,而不是数据类型。
' M3 O A& b. h, e) T0 gcreate 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 ));对于其他类型的观察,前两个字段将是相同的,除了检查限制外,强制为适当的类型。其他字段的编号、名称和数据类型可能不同。8 j' j; X- t6 l5 |9 d# m, N
让我们研究一个可能的存在Measurements表中元组示例:9 g8 m+ D; o7 u& k& t' `9 ?
ID ObservationKind Name Value ...==== =============== ========= =====1001 M CPU Usage 55.0 ...为了使这个元组存在于这个表中,观察表中必须首先有一个匹配条目ID值为1001,观察类型值为
2 _; n$ }8 d. \M”。ID任何值1001的其他项目都不能存在于观察表或测量表中,也不能存在于任何其他类型表(事件、状态)中。所有类型的表都以相同的方式工作。 b* v. y0 F' @3 r0 M
为了将每一种观察与主要观察表连接起来,我将进一步建议创建一个视图:& `) @! c, X* F/ g
create view MeasurementObservations as select ... from Observations o join Measurements m on m.ID = o.ID;任何只适用于测量的代码都只需点击此视图,而不是基本表。使用视图在应用程序代码和原始数据之间创建抽象墙,大大提高了数据库的可维护性。
. K% x/ w7 @' |+ X8 G7 v$ U现在,创建另一个观察值,如 Error涉及对ObservationKinds简单插入句子: M: S4 ]1 f0 M$ [7 p
F Fault A fault or error has been detected.当然,你需要为这些错误的观察创建一个新的表和视图,但它不会影响现有的表、视图或应用程序代码(当然,除了与新观察一起编写新代码) 。 |
|
|
|
|
|