![]() | |
![]() |
| | Thread Tools | Display Modes |
#1
| |||
| |||
|
#2
| ||||
| ||||
|
|
Im trying to design a database to hold metadata for video, image and audio clips. The current prototype (read quick dirty hack) has two tables: tblMedia id,metaid tblMeta id,fieldname,value This lets any given metaid have multiple pieces of metadata associated with it. The value field is meant to hold any data type, from boolean values to large amounts of text. |
|
To normalise this database I decided that I need to separate the tables as follows: tblMedia id,metaid This table contains a list of media items and the associated metadata id. There could be multiple pieces of metadata per media item. tblMediaMetaRef metaid,datatypeid This table lists the metaids and what datatype each metadata is. tblMetaDataTypes id,type This table lists the different type of datatype we want to store. My idea would be to then have a table for each type of metadata data type that I wanted to store. |
|
My concern is firstly how sensible is this design? |
|
Secondly is there a better way of doing it? Finally if I am on the right track how can I pull the results from the server in a single SQL query as this design would require a select statement for each piece of meta? |

#3
| |||
| |||
|
|
Im trying to design a database to hold metadata for video, image and audio clips. The current prototype has two tables: tblMedia (id, metaid) tblMeta (id, fieldname, value) My concern is firstly how sensible is this design? Secondly is there a better way of doing it? |
#4
| |||
| |||
|
|
Im trying to design a database to hold metadata for video, image and audio clips. The current prototype has two tables: tblMedia (id, metaid) tblMeta (id, fieldname, value) My concern is firstly how sensible is this design? Secondly is there a better way of doing it?EAV-type designs in RMDBs have advantages and disadvantages. In many cases, they become unpractical due to reduced SQL support / performance and increased coding/query complexity. You may be interested to read the closely related thread titled "Generalised Approach To Storing Address Details" in comp.databases.theory. |
#5
| |||||
| |||||
|
|
Im trying to design a database to hold metadata for video, image and audio clips. |
|
This lets any given metaid have multiple pieces of metadata associated with it. The value field [sic] is meant to hold any data type, from boolean[sci] values to large amounts of text. |
|
My concern is firstly how sensible is this design? |
|
Secondly is there a better way of doing it? |
|
Finally if I am on the right track how can I pull the results from the server in a single SQL query as this design would require a select statementfor each piece of meta? |
#6
| |||
| |||
|
|
The problem with EAV is not "SQL support". The problem is more fundamental than that. |
|
Bill covered it well, so I won't repeat it. EAV is just a poor choice. |
#7
| |||
| |||
|
|
Original RMDB Example: INSERT INTO EAV_DATA VALUES (1, 'LOCATION', 'Bedroom'); INSERT INTO EAV_DATA VALUES (1, 'EVENT', 'other'); INSERT INTO EAV_DATA VALUES (1, 'EVENT', 'bad behavior'); INSERT INTO EAV_DATA VALUES (2, 'LOCATION', 'Bedroom'); INSERT INTO EAV_DATA VALUES (2, 'EVENT', 'other'); INSERT INTO EAV_DATA VALUES (2, 'EVENT', 'verbal aggression'); INSERT INTO EAV_DATA VALUES (3, 'LOCATION', 'courtyard'); INSERT INTO EAV_DATA VALUES (3, 'EVENT', 'other'); INSERT INTO EAV_DATA VALUES (3, 'EVENT', 'peer'); |
|
CREATE TABLE EAV -- no key declared (key_col VARCHAR (10) NULL, attrib_value VARCHAR (50) NULL); INSERT INTO EAV VALUES ('LOCATION', 'Bedroom'); INSERT INTO EAV VALUES ('LOCATION', 'Dining Room'); INSERT INTO EAV VALUES ('LOCATION', 'Bathroom'); INSERT INTO EAV VALUES ('LOCATION', 'courtyard'); INSERT INTO EAV VALUES ('EVENT', 'verbal aggression'); INSERT INTO EAV VALUES ('EVENT', 'peer'); INSERT INTO EAV VALUES ('EVENT', 'bad behavior'); INSERT INTO EAV VALUES ('EVENT', 'other'); CREATE TABLE EAV_DATA -note lack of constraints, defaults, DRI (id INTEGER IDENTITY (1, 1) NOT NULL, bts_id INTEGER NULL, key_col VARCHAR (10) NULL, attrib_value VARCHAR (50) NULL ); INSERT INTO EAV_DATA VALUES (1, 'LOCATION', 'Bedroom'); INSERT INTO EAV_DATA VALUES (1, 'EVENT', 'other'); INSERT INTO EAV_DATA VALUES (1, 'EVENT', 'bad behavior'); INSERT INTO EAV_DATA VALUES (2, 'LOCATION', 'Bedroom'); INSERT INTO EAV_DATA VALUES (2, 'EVENT', 'other'); INSERT INTO EAV_DATA VALUES (2, 'EVENT', 'verbal aggression'); INSERT INTO EAV_DATA VALUES (3, 'LOCATION', 'courtyard'); INSERT INTO EAV_DATA VALUES (3, 'EVENT', 'other'); INSERT INTO EAV_DATA VALUES (3, 'EVENT', 'peer'); Ideally, the result set of the query would be Location Event count (headings if possible) Bedroom verbal aggression 1 Bedroom peer 0 Bedroom bad behavior 0 Bedroom other 2 Dining Room verbal aggression 0 Dining Room peer 0 Dining Room bad behavior 0 Dining Room other 0 Bathroom verbal aggression 0 Bathroom peer 0 Bathroom bad behavior 0 Bathroom other 0 courtyard verbal aggression 0 courtyard peer 1 courtyard bad behavior 0 courtyard other 1 Also, if possible, another query would return this result set. (I think I know how to do this one.) Location Event count Bedroom verbal aggression 1 Bedroom other 2 courtyard peer 1 courtyard other 1 Here is an answer From: Thomas Coleman SELECT Locations.locationvalue, Events.eventvalue, (SELECT COUNT(*) FROM (SELECT LocationData.locationvalue, EventData.eventvalue FROM (SELECT TD1.bts_id, TD1.value AS locationvalue FROM eav_data AS TD1 WHERE TD1.key = 'location') AS LocationData INNER JOIN (SELECT TD2.bts_id, TD2.value AS eventvalue FROM eav_data AS TD2 WHERE TD2.key = 'event' ) AS EventData ON LocationData.bts_id = EventData.bts_id ) AS CollatedEventData WHERE CollatedEventData.locationvalue = Locations.locationvalue AND CollatedEventData.eventvalue = Events.eventvalue FROM (SELECT T1.value AS locationvalue FROM EAV AS T1 WHERE T1.key = 'location') AS Locations, (SELECT T2.value AS eventvalue FROM EAV AS T2 WHERE T2.key = 'event') AS Events ORDER BY Locations.locationvalue, Events.eventvalue , SELECT Locations.locationvalue, Events.eventvalue (SELECT COUNT(*) FROM (SELECT LocationData.locationvalue, EventData.eventvalue FROM (SELECT TD1.bts_id, TD1.value AS locationvalue FROM eav_data AS TD1 WHERE TD1.key = 'location') AS LocationData INNER JOIN (SELECT TD2.bts_id, TD2.value AS eventvalue FROM eav_data AS TD2 WHERE TD2.key = 'event') AS EventData ON LocationData.bts_id = EventData.bts_id) AS CollatedEventData WHERE CollatedEventData.locationvalue = Locations.locationvalue AND CollatedEventData.eventvalue = Events.eventvalue) FROM (SELECT T1.value AS locationvalue FROM EAV AS T1 WHERE T1.key = 'location') AS Locations, (SELECT T2.value AS eventvalue FROM EAV AS T2 WHERE T2.key = 'event') AS Events; |
#8
| |||
| |||
|
|
Bill covered it well, so I won't repeat it. EAV is just a poor choice. Yes, Bill covered it well. In some cases where one needs to manage varied data structures including those not known at design-time, one may benefit by utilizing some level of EAV-type design. |
|
If you have a non-EAV schema for OP's requirements, please post it. |
#9
| |||
| |||
|
|
Neo wrote: Bill covered it well, so I won't repeat it. EAV is just a poor choice. Yes, Bill covered it well. In some cases where one needs to manage varied data structures including those not known at design-time, one may benefit by utilizing some level of EAV-type design. That just does not follow. The disadvantages are enormous, well-attested and plain to every systems integrator or BI / MIS professional who knows and loathes that so-called "model". |
#10
| ||||
| ||||
|
|
The problem with EAV is not "SQL support". The problem is more fundamental than that. Note, encoding data as EAVs by itself is fine. It works well in a db like dbd and non-dbs such as Prolog. |
|
EAVs are closely related to the well-founded FOL. RM/RMDBs can't manage complex EAVs in a systematic manner. |
|
Try replicating the example below. |
|
Bill covered it well, so I won't repeat it. EAV is just a poor choice. Yes, Bill covered it well. In some cases where one needs to manage varied data structures including those not known at design-time, one may benefit by utilizing some level of EAV-type design. If you have a non-EAV schema for OP's requirements, please post it. |
![]() |
| Thread Tools | |
| Display Modes | |
| |