【发布时间】:2012-08-21 07:39:27
【问题描述】:
我需要在数据库中创建一个数据库。这个问题与this 有关。我将尝试详细解释我正在尝试做的事情并提供代码示例。基本上,我希望能够在数据库中创建动态表。例如,我将有一个网页,允许用户使用列和数据创建自己的表。这是我想出的数据库设计:
aColumn
aDataType
aRow
aTable
zBit
zDateTime
zMoney
zNumber
zText
以z 开头的表是特定数据进入的数据,例如整数、日期时间值等。aColumn 是属于特定表的列。 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))
这是我用来启动和运行它的一些示例数据:
表格
Id Name
1 Users
aColumns
Id Name aTable aDataType
1 Name 1 2
2 UserId 1 1
3 Occupation 1 2
aDataType
Id Name
1 Number
2 Text
一行
Id aTable
1 1
2 1
一个数字
Id aRow aColumn Data
1 1 1 1245
2 2 2 56
文本
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* 表)由一行和一列标识。当我运行这个查询时,我得到这个:
结果
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
这是我想要的结果: (如果列未知,我不确定如何将这些行转换为列)
Row UserId Name
1 1245 Sara
2 56 Jake
大问题 这张表应该有 3 列还记得吗?
aColumns
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
在结果中,我还需要对列进行排序。这甚至可能吗。哪些数据库支持这种功能。我对任何可以做到这一点的数据库持开放态度。
【问题讨论】:
-
我需要在一个数据库中创建一个数据库。 为什么?简单地添加和删除列和/或表有什么问题。
-
见en.wikipedia.org/wiki/Inner-platform_effect 和thedailywtf.com/Articles/The_Inner-Platform_Effect.aspx。您为什么要重新发明*,而不是让您的应用程序动态地创建真正的行和列?
-
@ChrisShain - 动态创建新行/列的问题是如何编写查询,因为每个查询都需要查找存在哪些列,然后动态地允许人们选择要检索的内容.基本上,您正在为流程中的 EAV 模型创建框架。
-
对,但你也需要用你的方法做到这一点。 MySQL、Oracle 和 SQL Server 都有用于检索现有数据库结构的内置方法。恕我直言,EAV 的更大优势在于能够高效地存储稀疏数据,许多数据库引擎已经做到了这一点(请参阅 SQL Server 的面向列的存储)
-
欢迎来到数据库世界。我怀疑每个数据库开发人员都会经历这个阶段,直到他们了解“EAV”这个术语并开始阅读它。然而,如果你只是在玩,玩得开心,并以艰难的方式自己学习——这通常是最好的学习方式。祝你好运:)
标签: mysql sql sql-server oracle postgresql