Mysql 数据库中的数据库(表设计)

Mysql 数据库中的数据库(表设计),mysql,sql,sql-server,oracle,postgresql,Mysql,Sql,Sql Server,Oracle,Postgresql,可能重复: 我需要在数据库中创建一个数据库。这个问题涉及到。我将尝试详细解释我要做的事情,并提供代码示例。基本上,我希望能够在数据库中创建动态表。例如,我将有一个网页,允许用户使用列和数据创建自己的表。以下是我提出的数据库设计: aColumn aDataType aRow aTable zBit zDateTime zMoney zNumber zText 以z开头的表是特定数据进入的数据,如int、datetime值等。列是属于特定表的列。aRow标识aTable中的特定行。以下是数据库

可能重复:

我需要在数据库中创建一个数据库。这个问题涉及到。我将尝试详细解释我要做的事情,并提供代码示例。基本上,我希望能够在数据库中创建动态表。例如,我将有一个网页,允许用户使用列和数据创建自己的表。以下是我提出的数据库设计:

aColumn
aDataType
aRow
aTable
zBit
zDateTime
zMoney
zNumber
zText
z
开头的表是特定数据进入的数据,如int、datetime值等。列是属于特定表的列。aRow标识aTable中的特定行。以下是数据库设计:

aTable: Id, name
aColumn: Id, Name, aTable, aDataType
aDataType: Id, Name
aRow: Id, aTable
zBit: Id, aRow, aColumn, Data(Bit)
zDateTime: Id, aRow, aColumn, Data (DateTime)
zMoney: Id, aRow, aColumn, Data (Money)
zNumber: Id, aRow, aColumn, Data (INT)
zText: Id, aRow, aColumn, Data (nvarchar(MAX))
下面是我用来启动和运行它的一些示例数据:

aTable

Id          Name
1           Users
Id          Name
1           Number
2           Text
aColumns

Id          Name           aTable       aDataType
1           Name           1            2
2           UserId         1            1
3           Occupation     1            2
Table       Column         DataType     Row           Data
1           UserId         Number       1             1245          
1           UserId         Number       2             56
1           Name           Text         1             Sara
1           Name           Text         2             Jake
Id          Name           aTable       aDataType
1           Name           1            2
2           UserId         1            1
3           Occupation     1            2
aDataType

Id          Name
1           Users
Id          Name
1           Number
2           Text
aRow

Id          aTable
1           1
2           1
a数量

Id          aRow           aColumn      Data
1           1              1            1245
2           2              2            56
aText

Id          aRow           aColumn      Data
1           1              1            Sara
2           2              1            Jake
所有其他z*表均为空

以下是创建动态表的查询:

select t.[Id] as [Table], c.Name as [Column], dt.Name as [DataType], r.[Id] as [Row], cast(v.Data as nvarchar(MAX)) as Data from [pod].[dbo].[aTable] t
INNER JOIN [pod].[dbo].[aColumn] c on t.Id = c.[aTable]
INNER JOIN [pod].[dbo].[aDataType] dt on c.[aDataType] = dt.Id
INNER JOIN [pod].[dbo].[aRow] r on t.[Id] = r.[aTable]
INNER JOIN [pod].[dbo].[zBit] v on c.[Id] = v.aColumn and r.[Id] = v.[aRow]
UNION ALL
select t.[Id] as [Table], c.Name as [Column], dt.Name as [DataType], r.[Id] as [Row], cast(v.Data as nvarchar(MAX)) as Data from [pod].[dbo].[aTable] t
INNER JOIN [pod].[dbo].[aColumn] c on t.Id = c.[aTable]
INNER JOIN [pod].[dbo].[aDataType] dt on c.[aDataType] = dt.Id
INNER JOIN [pod].[dbo].[aRow] r on t.[Id] = r.[aTable]
INNER JOIN [pod].[dbo].[zDateTime] v on c.[Id] = v.aColumn and r.[Id] = v.[aRow]
UNION ALL
select t.[Id] as [Table], c.Name as [Column], dt.Name as [DataType], r.[Id] as [Row], cast(v.Data as nvarchar(MAX)) as Data from [pod].[dbo].[aTable] t
INNER JOIN [pod].[dbo].[aColumn] c on t.Id = c.[aTable]
INNER JOIN [pod].[dbo].[aDataType] dt on c.[aDataType] = dt.Id
INNER JOIN [pod].[dbo].[aRow] r on t.[Id] = r.[aTable]
INNER JOIN [pod].[dbo].[zMoney] v on c.[Id] = v.aColumn and r.[Id] = v.[aRow]
UNION ALL
select t.[Id] as [Table], c.Name as [Column], dt.Name as [DataType], r.[Id] as [Row], cast(v.Data as nvarchar(MAX)) as Data from [pod].[dbo].[aTable] t
INNER JOIN [pod].[dbo].[aColumn] c on t.Id = c.[aTable]
INNER JOIN [pod].[dbo].[aDataType] dt on c.[aDataType] = dt.Id
INNER JOIN [pod].[dbo].[aRow] r on t.[Id] = r.[aTable]
INNER JOIN [pod].[dbo].[zMoney] v on c.[Id] = v.aColumn and r.[Id] = v.[aRow]
UNION ALL
select t.[Id] as [Table], c.Name as [Column], dt.Name as [DataType], r.[Id] as [Row], cast(v.Data as nvarchar(MAX)) as Data from [pod].[dbo].[aTable] t
INNER JOIN [pod].[dbo].[aColumn] c on t.Id = c.[aTable]
INNER JOIN [pod].[dbo].[aDataType] dt on c.[aDataType] = dt.Id
INNER JOIN [pod].[dbo].[aRow] r on t.[Id] = r.[aTable]
INNER JOIN [pod].[dbo].[zNumber] v on c.[Id] = v.aColumn and r.[Id] = v.[aRow]
UNION ALL
select t.[Id] as [Table], c.Name as [Column], dt.Name as [DataType], r.[Id] as [Row], cast(v.Data as nvarchar(MAX)) as Data from [pod].[dbo].[aTable] t
INNER JOIN [pod].[dbo].[aColumn] c on t.Id = c.[aTable]
INNER JOIN [pod].[dbo].[aDataType] dt on c.[aDataType] = dt.Id
INNER JOIN [pod].[dbo].[aRow] r on t.[Id] = r.[aTable]
INNER JOIN [pod].[dbo].[zText] v on c.[Id] = v.aColumn and r.[Id] = v.[aRow]
以下是此查询的一个块:

select t.[Id] as [Table], c.Name as [Column], dt.Name as [DataType], r.[Id] as [Row], cast(v.Data as nvarchar(MAX)) as Data from [pod].[dbo].[aTable] t
INNER JOIN [pod].[dbo].[aColumn] c on t.Id = c.[aTable]
INNER JOIN [pod].[dbo].[aDataType] dt on c.[aDataType] = dt.Id
INNER JOIN [pod].[dbo].[aRow] r on t.[Id] = r.[aTable]
INNER JOIN [pod].[dbo].[zText] v on c.[Id] = v.aColumn and r.[Id] = v.[aRow]
正如您在这里看到的,一段数据(z*表)由一行和一列标识。当我运行此查询时,我得到以下信息:

结果

Id          Name           aTable       aDataType
1           Name           1            2
2           UserId         1            1
3           Occupation     1            2
Table       Column         DataType     Row           Data
1           UserId         Number       1             1245          
1           UserId         Number       2             56
1           Name           Text         1             Sara
1           Name           Text         2             Jake
Id          Name           aTable       aDataType
1           Name           1            2
2           UserId         1            1
3           Occupation     1            2
以下是我想要的结果: (如果列是未知的,我不知道如何将这些行转换为列)


大问题 这个表应该有3列,记得吗

aColumns

Id          Name           aTable       aDataType
1           Name           1            2
2           UserId         1            1
3           Occupation     1            2
Table       Column         DataType     Row           Data
1           UserId         Number       1             1245          
1           UserId         Number       2             56
1           Name           Text         1             Sara
1           Name           Text         2             Jake
Id          Name           aTable       aDataType
1           Name           1            2
2           UserId         1            1
3           Occupation     1            2

因此,我的最终预期结果是:

Row         UserId       Name         Occupation
1           1245         Sara         NULL
2           56           Jake         NULL

在结果中,我还需要对列进行排序。这可能吗。哪些数据库支持这种功能。我对任何能够做到这一点的数据库都持开放态度。

那么,您可能想看看您的数据设计

基本上,您可以有一个带有表名的表,以及表上的一些其他元数据

然后,您可以为这些行中的每一行创建一个表,以包含列数据,例如数据类型和名称

然后,您有一个表格,在其中您将每列的值放在一个长表格中

这允许您动态创建表,或动态添加/删除行

要比较relational和EAV,您可以查看以下问题:

但是,如果您想拥有此数据的关系视图,那么您需要创建触发器来帮助保持视图的最新状态,要使其正常工作,这可能需要大量的工作。如果您不需要关系视图,那么就可以了

另一种方法是使用NoSQL数据库(),因为不必设置模式,所以您可以只存储该行所需的列


在这一点上,我将采用NoSQL方式,因为有许多数据库可以工作,并且您需要进行的重新设计是最少的。

您可能需要查看数据的设计

基本上,您可以有一个带有表名的表,以及表上的一些其他元数据

然后,您可以为这些行中的每一行创建一个表,以包含列数据,例如数据类型和名称

然后,您有一个表格,在其中您将每列的值放在一个长表格中

这允许您动态创建表,或动态添加/删除行

要比较relational和EAV,您可以查看以下问题:

但是,如果您想拥有此数据的关系视图,那么您需要创建触发器来帮助保持视图的最新状态,要使其正常工作,这可能需要大量的工作。如果您不需要关系视图,那么就可以了

另一种方法是使用NoSQL数据库(),因为不必设置模式,所以您可以只存储该行所需的列


在这一点上,我将采用NoSQL方式,因为有许多数据库可以工作,并且您需要进行的重新设计非常少。

对于问题的最后一部分,您将询问如何对EAV模式进行查询。一些数据库通过对SQL标准的扩展来支持这一点,而另一些数据库则根本不支持。为了便于携带,您必须在应用程序中实现。PostgreSQL为此提供了最新的解决方案

如果你走这条路,你迟早会后悔的。它在某些有限的情况下是有用的,但是它不适合关系模型,并且会导致很多痛苦和问题,其中最重要的是糟糕的性能

相反,请考虑:

  • 如果可能的话,重新设计,这样就不需要动态模式。在您的情况下可能不可能,因为您的明确需求是基于web的数据库应用程序的用户可编辑模式,但在大多数情况下,这是正确的选择

  • 使用
    ALTER TABLE
    create TABLE
    等动态创建/删除模式。一些数据库在这方面比其他数据库好得多。PostgreSQL的事务性DDL非常有用。要避免这成为性能和维护的噩梦,需要谨慎,但如果您试图用动态结构对关系数据库建模,这可能是最明智的选择

  • 为类似EAV的查询而优化的键/值存储;看见请注意,这些系统中的许多都不提供完整的ACID语义,并且可能具有有限的查询语言,因此您可以在应用程序中完成更多的工作

  • 在数据库中存储XML或JSON。您可以使用关系数据库来实现这一点,但使用文档数据库可能会更好。与K/V商店相同的注意事项也适用。如果您在应用程序中执行所有查询逻辑,并且您的数据量不太大,那么这种方法可以正常工作

  • 使用特定于数据库的功能,如PostgreSQL的
    hstore
    ,在需要时支持任意键/值存储,并在不需要k/v的情况下使用标准关系设计。如果您希望将关系作为输出,那么它仍然是一个主要的PITA,涉及低效的交叉表查询和连接

这是一个很好的观点: