tabelle esterne anonime

Salve avrei la necessità di generalizzare delle tabelle esterne, cioè chiamarle con nomi che terminano con numerazione (es. tabella1; tabella2; etc…) e avere dentro la tabella principale le relative chiavi (chiave1, chiave2, etc…)

dunque avrei

  • una tabellaPrincipale: id; fk1; fk2; fk3; fk4

  • 4 tabelle (collegate N:1 a tabellaPrincipale) che si chiameranno tabella1; tabella2; tabella3, tabella4

tutto ciò per far decidere all’utente finale il nome e l’ordine di questi 4 modelli.

Da dove iniziereste ? :)

grazie

Metterei 4 riferimenti nella funzione

relations()

del tipo:




	public function relations()

	{

		return array(

			'obj1' => array(self::HAS_MANY, 'Tabella1', 'fk1'),

            

		);

	}



chiaramente il tipo di relazione (HAS_MANY) dipende da che tipo di relazione c’è tra i record.

Si giusto ma in questo caso non conosco nè l’ordine e nè la quantità, l’utente finale può sfruttarle tutte come solo una o due di queste tabelle esterne, e nemmeno quale alias deciderà di applicare a quelle scelte.

In una pagina /site/settings proporrò 4 inputs ordinati (1,2,3,4) , e l’utente gli assegnerà dei nomi (alias), dunque delle relations() dinamiche ? Si potrà mai ? :huh:

th4nks

Forse allora bisogna approcciarsi al problema in maniera differente.

Spiegami meglio il problema da risolvere.

Si :) allora, avrei un oggetto (model) X con tante caratteristiche altezza_fk, larghezza_fk, peso_fk etc… con relative tabelle join tbl_altezza, tbl_larghezza, tbl_peso (N:1)

Ora dato che non sò quali e quanti di queste caratteristiche vorrà sfruttare l’utente finale, son disposto a generalizzare, dunque avrò:

Un model principale "X" con le chiavi esterne che si chiameranno 01_fk; 02_fk; 03_fk e e relative tabelle join prenderanno il nome di tbl_01; tbl_02; tbl_03

In questa maniera mi basterà proporre N input all’utente finale, dentro i quali inserirà un ‘alias’ per ogni elemento (es. tbl_01 sarà “Pippo” per l’utente, tbl_02=>“Paperino”) credo che mi servirà una ulteriore tabella per mantenere la relazione tra nome reale del modello (tabella) e l’alias scelto… spero di aver reso la cosa un pò + chiara di prima ;)

th4nks

Ho capito.

A questo punto farei una tabella generica del tipo:

Tabella Caratteristiche:

  • id_esterno:int;

  • caratteristica:enum(altezza, larghezza, peso, …) o anche string la lista di scelte è dinamica;

  • valore:string(?);

In questo modo fai il link tramite la chiave id_esterno e poi nel CDbCriteria puoi aggiungere altre condizioni quando agganci la relation tramite with, del tipo:




$c = 'altezza';

$criteria = new CDbCriteria();

$criteria->with = array('caratteristiche' => array('condition' => 'caratteristiche.caratteristica = "'.$c.'"'));



Eh no ‘altezza’ è il nome che conosco io … ma l’utente può tranquillamente chiamarmela “topolino” dalla pagina delle impostazioni :mellow:

Perfetto, allora è sufficiente impostare il campo "caratteristica" come string, in modo tale che sia dinamico.

L’unica cosa è che se l’utente cambia il nome a caratteristica, perde tutti i riferimenti.

Eventualmente puoi usare una tabella di passaggio, del tipo:

Tabella caratteristiche_nomi:

  • id:int;

  • id_esterno:int (collegamento al model X);

  • nome:string;

Tabella caratteristiche_valori:

  • id:int;

  • id_caratteristica_nome:int (collegamento a caratteristiche_nomi);

  • valore:string (così è più generico, poi al massimo fai i cast in base al tipo finale);

In questo modo se cambi il nome della caratteristica, non perdi nessun valore.

Scusami forse ho spiegato male le relazioni, in realtà il model X ha al suo interno tante chiavi esterne quante sono le caratteristiche (tabelle esterne) :unsure:

Quindi model sarà:

Tabella model:

  • id_fk1;

  • id_fk2;

  • id_fk3;

Tabella caratteristiche_nomi:

  • id:int;

  • nome:string;

Quindi id_fk1 sarà collegato ad un id di caratteristiche_nomi e

così per gli altri indici id_fk.

Uhm… ma in questa maniera non potrò gestire il crud di ogni ‘caratteristica’ dovrei poter inserire/modificare N altezze… N pesi… e filtrare/cercare anche in base a queste tabelle. Non credo potrò riunire tutti questi dati in una unica table :expressionless: giusto ?

Ad occhio non mi sembra ci siano dei problemi con le crud,

infatti puoi ragionare per caratteristica in questo modo:

se ad esempio $c = ‘peso’, hai una select di questo tipo:




select

cv.*

from caratteristiche_nomi cn

INNER JOIN caratteristiche_valori cv

ON cn.id = cv.id_caratteristica_nome

WHERE cn.nome = $c



quindi tutti i valori di caratteristiche_valori vengono restituiti per caratteristica (in questo caso ‘peso’).

Comunque nel caso più generico ci vogliono 2 tabelle, in modo che se si cambia il nome alla caratteristica (da ‘peso’ a ‘peso totale’ per esempio), non si perdono i collegamenti.

Se volessi agg/rimuovere un ‘peso’ o un ‘altezza’ o altra caratteristica ? Tutto dentro una tabella …uhm…

Infatti una cosa a cui stavo riflettendo è che toglierei tutte le chiavi esterne dal model e lascerei il riferimento in caratteristiche_nomi così da avere la flessibilità di aggiungere quante caratteristiche vuoi al model. Così depure il model dalle chiavi esterne e formalizzi:

Tabella caratteristiche_nomi:

  • id

  • id_model

  • nome

Per aggiungere una nuova caratteristica ad un determinato model è sufficiente aggiungere un nuovo record in caratteristiche_nomi.

Ma avrei ridondanza…

Tabella caratteristiche_nomi:

> id; ‘altezza’; model_id

> id; ‘altezza’, model_id

:mellow:

No, non hai ridondanza, perchè poi c’è la tabella caratteristiche_valori (che ho scritto qualche post fa…) dove vai ad aggiungere i valori.

Per cui

Tabella caratteristiche_nomi:

id:1, id_model:1,nome:‘altezza’,

Tabella caratteristiche_valori:

id:1, id_caratteristica_nome:1, valore:‘1.51’,

id:2, id_caratteristica_nome:1, valore:‘1.71’,

Grazie mille ;) provo e ti aggiorno subito

Figurati, di nulla.