Programming Logic in Storing Multiple table ids in one table - data-modeling

I have Five Tables as Below
1.tblFruits
2.tblGroceries
3.tblVegetables
4.tblPlants
5.tblDescriptions
All the tables except 5th one tblDescriptions will have ids as one column and as primary key and Items as Second Column.
The column in table 1 to table 4 are similar and as follows
ids item_name
Now i want to store description of the items of the four table in the fifth table as below
Desc_Id Description Ids
Now the problem is since i am storing the ids to identify the description of the items in the other four table i might get similar ids when i put ids of four table together.
Let me know the table design for the above requirement

tblDescription
=====================
id | pk_id | description | type
id : auto_generated id of tblDescription
pk_id : foreign key to linked to the tblFruits,tblGroceries.. table
description : the description
type : value either be fruits, groceries,vegetables,plants .To identify the table.
SQL to extract description would be as below:
Select f.item_name, d.description from tblDescription d
inner join tblFruits f on d.pk_id=f.id and d.type='fruits'
inner join tblGroceries g on d.pk_id=g.id and d.type='groceries'

Use Polymorphic Association. As foreign key of your 5th table with description use two columns object_id and object_model.
Example of table content:
Desc_Id Description Object_ID Object_Model
1 'dsferer' 12 `Fruit`
2 `desc2 12 `Vegetable`
2 `descfdfd2 19 `Vegetable`
Remember to add unique index on both columns for performance reasons.
Here you have some article explaining this in PHP

As your tables are similar, the best practice is to combine all of your tables and even description and define row type using a type column.
id name description type
[Fruits, Groceries, Vegetables, Plants]
It's easier to understand and maintain.
But if your tables are different you have two option:
1- use a super table for your types which produce unique IDs which I suggest.
2- use a type row in your description field and define it as primary key beside ID in that table.

Related

What's the cleanest way in SQL to break a table into two tables?

I have a table that I want to break into 2 tables. I want to pull some data out of table A, put it into a new table B, and then point each record in A to the corresponding record in the new table.
It's easy enough to populate the new table with an INSERT INTO B blah blah SELECT blah blah FROM A. But the catch is, when I create the new records in B, I want to write the ID of the B record back into A.
I've thought of two ways to do this:
Create a cursor, loop through A a record at a time, create the record in B and post the new ID back to A.
Create a temporary table with the extracted data, an ID for the new record, and the ID of A. Then use this temporary table to populate B and also to post the ID back to A.
Both methods seem cumbersome with a lot of copying all the data back and forth. Is there a clean, simple way to do this or should I just knuckle down and do it the hard way?
Oh, I'm using Microsoft SQL Server, if your answer depends on non-standard features of SQL.
Someone asks for an example. Yes, I should have included something concrete to make it clear. The real example is a bunch of data, but let me give a simplified example of what I mean.
Let's say I have a Customer table with customer_id, name, and city. I want to break city out into a separate table.
So for example:
Customer
ID Name City
17 Al Detroit
22 Betty Baltimore
39 Charles Cleveland
I want to convert this to:
Customer
ID Name City_ID
17 Al 1
22 Betty 2
39 Charles 3
City
ID Name
1 Detroit
2 Baltimore
3 Cleveland
The exact ID values don't matter.
So easy enough to create the City table and the reference ...
create table city (id int identity primary key, name varchar(50))
alter table customer add city_id int references city
And then populate the city table ...
insert into city (name)
select city from customer
The trick is how to get those city IDs back into the Customer table.
(And yes, in this simplified example, the effort may appear pointless. In real life we have many tables with addresses and I want to pull all those fields out of all the other tables and put them into a single address table, so we can standardize the declarations and processing of addresses.)
(Note: I haven't tested the sample code above. Excuse me if there's a typo or something in there.)
You can use the output clause to capture your new ID values.
without any sample data or examples of what you are doing the following is just a guide.
Create a #table to hold the new ID values, then insert the newly inserted Id identity values along with a correlating value from the inserted virtual table. You can then update the original table with the new IDs by joining on this correlating value.
create table #NewIds (TableBId int, TableAId int)
insert into TableB (column list)
output inserted.Id, inserted.TableAId into #NewIds
select column list
from TableA
update a
set a.TableBId=Id
from #NewIds n join TableA a on a.Id=n.TableAId

Should I be using multiple PostgreSQL queries for this?

I have a couple of tables.
Table 1 (player_main)
This table has a "id" column which is a UUID type and is the primary key.
Table 2 (game_main)
This table also has an "id" column of the UUID type and is a primary key.
Table 3 (game_members)
This table has a column "member_id" of UUID type which is a primary key and a foreign reference to player_main(id).
There is also an "game_id" column of UUID type which references game_main(id).
My problem is, if a player connects to the server, I want to be able to load up their "game data" by querying the database and receiving all the data to construct their data object. I am given the UUID of the player which is stored in player_main(id). I need to obtain the game_main(id) and a list of all the game member ids that correspond to that game_main(id).
How would I do this? I've attempted to do different types of joins with a where clause to identify the game_members(member_id) but that only returns the row that is correspondent to the member that has just joined, not a column containing all of the members for that game.
Any help is appreciated, thank you.
Edit
I have tried the following query:
SELECT t1.member_id, t2.*
FROM game_members t1
INNER JOIN game_main t2
ON t1.game_id = t2.id
WHERE t1.member_id = <some UID>
which resulted in 1 row and 2 columns. The columns being "game_members.member_id" and "game_main.id". The value for the first column is the UUID that I specified in the where clause and the value for the second column is the UUID of the game. I was expecting to see 2 rows of data with the same "game_main.id" but with different "game_member.member_id"'s, as I have 2 entries in the same game currently.
Edit 2
As requested, I will provide sample data for my tables as well as the output that I wish to see.
Sample Data:
[player_main]
id
------------------------------------|
863fdf91-86fb-49a7-9232-bcb596e3a86f|
7af64cd7-72a2-410f-9b5c-620127fca0ac|
c7b1952a-b263-470f-9cae-9d5e6d7a8186|
[game_main]
id
------------------------------------|
dd76c680-5853-40a6-b757-0457d1a7e95f|
ca4f5b1f-0f8c-4f10-969c-464ccf207d9c|
[game_members]
member_id | game_id
------------------------------------|------------------------------------
863fdf91-86fb-49a7-9232-bcb596e3a86f|dd76c680-5853-40a6-b757-0457d1a7e95f
7af64cd7-72a2-410f-9b5c-620127fca0ac|dd76c680-5853-40a6-b757-0457d1a7e95f
c7b1952a-b263-470f-9cae-9d5e6d7a8186|ca4f5b1f-0f8c-4f10-969c-464ccf207d9c
[desired output]
This is what the game info of the player's current game should look like. The query should take only the player's UUID and return the following if I the UUID was equal to 863fdf91-86fb-49a7-9232-bcb596e3a86f
member_id | game_id
------------------------------------|------------------------------------
863fdf91-86fb-49a7-9232-bcb596e3a86f|dd76c680-5853-40a6-b757-0457d1a7e95f
7af64cd7-72a2-410f-9b5c-620127fca0ac|dd76c680-5853-40a6-b757-0457d1a7e95f
Try doing a self-join of the game_members table. The following query will generate all unique members who have any game in common with games used by a certain player.
SELECT DISTINCT t2.member_id, t1.game_id
FROM game_members t1
INNER JOIN game_members t2
ON t1.game_id = t2.game_id
WHERE t1.member_id = <some UID>
You could break down your problem into:
looking up the player's current game in game_members and then,
looking up the game's current players from the same game_members table
This approach translates to the following query involving a self-join:
select
gm2.member_id,
gm1.game_id
from
game_members gm1
inner join game_members gm2 on
gm1.game_id = gm2.game_id -- lookup the game's current players
where
gm1.member_id = '863fdf91-86fb-49a7-9232-bcb596e3a86f' -- lookup the player's current game

Qt: viewing data from tables with foreign key columns pointing to multiple other tables

I have a table Thingsies, with columns id, data1, otherTableId, otherTableRowId. I need the last two columns instead of just a foreign key column because depending on the Thingy the type of information I want there is different.
otherTableId references an id in the table OtherTables, which itself has columns called id and tableName. These tableNames are the names of other tables, like OtherTable1, OtherTable2.
The column otherTableRowId in Thingies references an id in the OtherTable given by otherTableId. The OtherTables themselves have more data in them. There's a one-to-one correspondence between Thingies and entries in one of the OtherTables. So the number of rows in Thingies is the total number of rows in all the OtherTables. (Is this bad design?)
I want to display Thingies in a QTableView that has columns for id, data1, and data2, where data2 is generated programatically from otherTableId and otherTableRowId. How should I proceed?
Thanks.
I think I've solved this. I'm using a QSqlQueryModel whose query is a union of a bunch of select statements, one for each OtherTable. Each select statement has to somehow merge (e.g., concatenate) the data unique to each OtherTable using a special expression anyway, so there's no use for me at least for the OtherTables table.

MS Access Relationship help needed

I have 2 MS Access Tables.
Table 1
id
room-name
Table 2
wall
cupboard
ceiling
Now... table1.room-name has the room names and table2 contains object (many) so each room name contains many objects.
My question is ... How do I set the relationships for this please?
Nothing in table 2 tells you what room things are in so you need to add a foreign key of the room to the primary key of table 1. In this case either column of table1 could be its primary key - I would use room- name and drop the id.
So table2 needs altering so that room-name is in it and the draw the connection from table1 to table2.
Something like:
[Room]
RoomId eg 1 2
RoomName eg bedroom kitchen
[RoomItem]
RoomItemId eg 1 eg 2 eg 3
RoomId eg 1 eg 1 eg 2
ItemName eg wardrobe eg bed eg cooker
Where the RoomId links the Room and RoomItem tables.

Datatype equivalent to SET in a database?

I want to use a SET datatype for my databse. So that a field of that type can contain one or more values from that data type.
But I have following two questions:
Q1. Is SET is correct to use as a datatype in a database? I think that its not supported by all the databases.
Q2. If SET is not a good option, then what can I use in place of SET?
You should use a table for this with a foreign key:
YourTable
col1 ...
col2 ...
YourTypeCol char(1) FK to YourTypeTable
col4 ...
YourTypeTable
YourTypeCol char(1) PK <<make the data type fix your "set"
YourTypeColDescription string
So for example, you'd have data like this:
CarTable
CarID int PK auto number
CarMaker int FK
CarBuilt date
....
CarID CarMaker CarBuilt
1 1 1/10/2005
2 4 3/18/2004
3 3 10/31/2009
...
CarMakerTable
CarMake int PK
CarMakeName string
CarMake CarMakeName
1 Ford
2 GM
3 Honda
4 Mazda
...
as for the So that a field of that type can contain one or more values from that data type I would not recommend this. It is best practice to store only one value per "field". Storing multiple values in a single field is against the principle of Database normalization and will result in issues when you try to pull particular items out of the "set". It is best to split each value into its own row, which means changing your table design. Supply more information about the data you are trying to store and I can recommend a table structure for you.

Resources