Si vous jamais prévoyez de rechercher des attributs spécifiques, c'est une mauvaise idée de les sérialiser dans une seule colonne, car vous devrez utiliser des fonctions par ligne pour obtenir les informations - cela évolue rarement bien.
J'opterais pour votre deuxième choix. Avoir une liste d'attributs dans une table attributaire, les objets dans leur propre table et une table de relations plusieurs-à-plusieurs appelée attributs d'objet.
Par exemple :
objects:
object_id integer
object_name varchar(20)
primary key (object_id)
attributes:
attr_id integer
attr_name varchar(20)
primary key (attr_id)
object_attributes:
object_id integer references (objects.object_id)
attr_id integer references (attributes.attr_id)
oa_value varchar(20)
primary key (object_id,attr_id)
Votre préoccupation concernant les performances est notée mais, d'après mon expérience, il est toujours plus coûteux de diviser une colonne que de combiner plusieurs colonnes. S'il s'avère qu'il y a des problèmes de performances, il est parfaitement acceptable de casser 3NF pour des raisons de performances.
Dans ce cas, je le stockerais de la même manière, mais j'aurais également une colonne avec les données brutes sérialisées. Si vous utilisez des déclencheurs d'insertion/mise à jour pour synchroniser les données en colonnes et combinées, vous n'aurez aucun problème. Mais vous ne devriez pas vous en soucier jusqu'à ce qu'un problème réel surgisse.
En utilisant ces déclencheurs, vous réduisez le travail requis à uniquement lorsque les données changent. En essayant d'extraire des informations de sous-colonne, vous effectuez un travail inutile sur chaque sélectionnez.