Pergunta

Eu tenho uma estrutura de mesa, não tenho muita certeza de como criar a melhor maneira.

Basicamente, tenho duas tabelas, tblsystemitems e tblclientItems. Eu tenho uma terceira tabela que possui uma coluna que faz referência a um 'item'. O problema é que esta coluna precisa fazer referência a um item do sistema ou um item cliente - não importa qual. Os itens do sistema têm chaves na faixa de 1..2^31, enquanto os itens do cliente têm chaves no intervalo -1 ..- 2^31, portanto, nunca haverá colisões.

Sempre que consultei os itens, estou fazendo isso através de uma visão que faz uma união tudo entre o conteúdo das duas tabelas.

Assim, de maneira ideal, gostaria de fazer uma referência de chave estrangeira o resultado da visão, pois a visualização sempre será a união das duas tabelas - mantendo os IDs únicos. Mas não posso fazer isso, pois não posso fazer referência a uma visualização.

Agora, eu posso simplesmente largar a chave estrangeira, e tudo está bem. No entanto, eu realmente gostaria de ter algumas funcionalidades nulas de exclusão/definir em cascata e em cascata. Existe alguma maneira de fazer isso, além de gatilhos?

Foi útil?

Solução

Desculpe pela resposta tardia, fiquei impressionado com um caso sério de fim de semana.

Quanto à utilização de uma terceira tabela para incluir PKs de tabelas de clientes e sistemas - não gosto disso, pois isso complica excessivamente a sincronização e ainda exige que meu aplicativo saiba da terceira tabela.

Outra questão que surgiu é que eu tenho uma terceira tabela que precisa fazer referência a um item - sistema ou cliente, isso não importa. Ter as tabelas separadas basicamente significa que eu preciso ter duas colunas, um clientesid e um sistema, cada uma com uma restrição para cada uma de suas tabelas com anulabilidade - bastante feia.

Acabei escolhendo uma solução diferente. Todo o problema foi sincronizar facilmente os novos itens do sistema nas tabelas sem mexer com os itens do cliente, evitar colisões e assim por diante.

Acabei criando apenas uma única tabela, itens. Os itens possuem uma coluna um pouco chamada "SystemItem" que define, bem, o óbvio. No meu banco de dados de desenvolvimento / sistema, eu tenho o PK como uma identidade int (1,1). Depois que a tabela foi criada no banco de dados do cliente, a chave de identidade é alterada para (-1, -1). Isso significa que os itens do cliente são negativos, enquanto os itens do sistema são positivos.

Para sincronizações, basicamente ignoro qualquer coisa com (SystemItem = 1) enquanto sincroniza o restante usando a inserção de identidade. Portanto, sou capaz de sincronizar enquanto ignora completamente os itens do cliente e evita colisões. Também sou capaz de fazer referência a apenas uma tabela de "itens" que cobre itens de clientes e do sistema. A única coisa a ter em mente é corrigir a tecla em cluster padrão, para que seja descendente para evitar todos os tipos de reestruturação de páginas quando o cliente inserir novos itens (atualizações do cliente vs atualizações do sistema é como 99%/1%).

Outras dicas

Você pode criar um ID exclusivo (db gerado - sequência, autoinc, etc.) para a tabela que faz referência a itens e criar duas colunas adicionais (tblSystemitemsfk e TblClientItemsfk) onde você faz referência aos itens do sistema e itens do cliente, respectivamente - algum Os bancos de dados permitem que você tenha uma chave estrangeira que é Nulível.

Se você estiver usando um ORM, poderá distinguir facilmente os itens do cliente e os itens do sistema (dessa forma, não precisa para identificadores negativos para impedir a sobreposição de ID) com base apenas nas informações da coluna.

Com um pouco mais de Bakcground/contexto, provavelmente é mais fácil determinar uma solução ideal.

You probably need a table say tblItems that simply store all the primary keys of the two tables. Inserting items would require two steps to ensure that when an item is entered into the tblSystemItems table that the PK is entered into the tblItems table.

The third table then has a FK to tblItems. In a way tblItems is a parent of the other two items tables. To query for an Item it would be necessary to create a JOIN between tblItems, tblSystemItems and tblClientItems.

[EDIT-for comment below] If the tblSystemItems and tblClientItems control their own PK then you can still let them. You would probably insert into tblSystemItems first then insert into tblItems. When you implement an inheritance structure using a tool like Hibernate you end up with something like this.

Add a table called Items with a PK ItemiD, And a single column called ItemType = "System" or "Client" then have ClientItems table PK (named ClientItemId) and SystemItems PK (named SystemItemId) both also be FKs to Items.ItemId, (These relationships are zero to one relationships (0-1)

Then in your third table that references an item, just have it's FK constraint reference the itemId in this extra (Items) table...

If you are using stored procedures to implement inserts, just have the stored proc that inserts items insert a new record into the Items table first, and then, using the auto-generated PK value in that table insert the actual data record into either SystemItems or ClientItems (depending on which it is) as part of the same stored proc call, using the auto-generated (identity) value that the system inserted into the Items table ItemId column.

This is called "SubClassing"

I've been puzzling over your table design. I'm not certain that it is right. I realise that the third table may just be providing detail information, but I can't help thinking that the primary key is actually the one in your ITEM table and the FOREIGN keys are the ones in your system and client item tables. You'd then just need to do right outer joins from Item to the system and client item tables, and all constraints would work fine.

I have a similar situation in a database I'm using. I have a "candidate key" on each table that I call EntityID. Then, if there's a table that needs to refer to items in more than one of the other tables, I use EntityID to refer to that row. I do have an Entity table to cross reference everything (so that EntityID is the primary key of the Entity table, and all other EntityID's are FKs), but I don't find myself using the Entity table very often.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top