Permalänk

MySQL hjälp!

Tjena!
Har en förfrågan som jag hoppas någon kan svara på!

Jag har två tabeller:
CREATE TABLE Products(
product_name varchar(50) not NULL,
PRIMARY KEY(product_name));

CREATE TABLE Ingrediens(
ingredient_name varchar(50) not NULL, in_stock double not NULL, last_ordered date not NULL,
PRIMARY KEY(ingredient_name));

Som framgår så finns ett produktnamn i ena tabellen och samtliga ingredienser som finns i lager i den andra.

Jag vill nu skapa en tabell Recipe där jag vill får hur mycket av någon ingrediens som behövs för en produkt. Jag vill alltså skapa en tabell med ett attribut som är produktnamnet (det vet jag hur man gör) och resten av attributen ska ju då vara alla ingredienser, dvs alla värden under INGREDIENT_NAME ska hamna som attribut!

Har letat både på Internet och i min fina bok, men hittar inget av värde!

Någon som har något förslag?

Visa signatur

MSI P67A-GD55 | Core i7 2600k @4.0 Noctua NH-D14| Corsair HX 650W | Corsair Dominato r8 GB | XFX Radeon 6950 2 GB | Samsung 500 GB + 2x 160 GB | Corsair Force 120 GB || NAD C326BEE | Cerwin Vega VS-10 | LG LH4000| Samsung SyncMaster EX2220

Permalänk
Medlem

för det första är det ingen bra idé att använda namnen som primär-nycklar. använd räknare istället.

vad du behöver är en relations-tabell, där varje rad pekar ut en unik kombination av produkt och ingrediens, samt ingrediensens mängd och enhet.
observera att produkt, ingrediens och enhet bör pekas ut med hjälp av ett id-nummer istället för text!

ex:

Produkt | Ingrediens | Mängd | Enhet -----------+----------------+-------+------ Lasagne | Lasagneplattor | 6 | st Lasagne | Tomatsås | 1 | l Lasagne | Hästkött | 500 | g Köttbullar | Hästkött | 100 | g Köttbullar | Bark | 600 | g Hamburgare | Hamburgerbröd | 1 | st Hamburgare | Blod | 1 | dl Hamburgare | Hjärta | 90 | g

Visa signatur

as far as we can tell, the massacre went well...

Permalänk
Medlem

CREATE TABLE Product ( productId int unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY, productName varchar(50) not NULL, in_stock enum("yes","no") not NULL default "no", last_ordered date not NULL, UNIQUE KEY (productName) ); insert into Product values (null,"Snask","yes",now()); CREATE TABLE Ingredient ( IngredientId int unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY, ingredientName varchar(50) not NULL, in_stock enum("yes","no") not NULL default "no", last_ordered date not NULL, UNIQUE KEY (ingredientName) ); insert into Ingredient values (null,"Snaskpulver","yes",now()); insert into Ingredient values (null,"Color Black","yes",now()); CREATE TABLE Recipe ( productId int unsigned not null, IngredientId int unsigned not null, ammount double not null, key(productId), key(IngredientId) ); insert into Recipe values (1,1,0.4); insert into Recipe values (1,2,0.1); Vad och hur mycket behövs för att göra produkten med id "1". select * from Recipe where productId = 1;

Permalänk

Som någon ovan nämnde så behöver du en relationstabell. Haha går du på LNU i Växjö? Har med dessa delar i vårt slutprojekt i SQL

Visa signatur

HTPC: Late 2014 Mac Mini
Bärbar: Mid 2012 MacBook Air

Permalänk
Skrivet av jovnas:

för det första är det ingen bra idé att använda namnen som primär-nycklar. använd räknare istället.

vad du behöver är en relations-tabell, där varje rad pekar ut en unik kombination av produkt och ingrediens, samt ingrediensens mängd och enhet.
observera att produkt, ingrediens och enhet bör pekas ut med hjälp av ett id-nummer istället för text!

ex:

Produkt | Ingrediens | Mängd | Enhet -----------+----------------+-------+------ Lasagne | Lasagneplattor | 6 | st Lasagne | Tomatsås | 1 | l Lasagne | Hästkött | 500 | g Köttbullar | Hästkött | 100 | g Köttbullar | Bark | 600 | g Hamburgare | Hamburgerbröd | 1 | st Hamburgare | Blod | 1 | dl Hamburgare | Hjärta | 90 | g

Just en relationsmodell jag behöver ja, och jag använder ID i min databas, men jag skrev inte med alla attribut!
Jag ville undvika att ha upprepning på alla produkter i tabellen, därför jag efterfrågade en annan design om det var möjligt!

Skrivet av Supermotard:

Som någon ovan nämnde så behöver du en relationstabell. Haha går du på LNU i Växjö? Har med dessa delar i vårt slutprojekt i SQL

Haha nej, detta är på Lth

Visa signatur

MSI P67A-GD55 | Core i7 2600k @4.0 Noctua NH-D14| Corsair HX 650W | Corsair Dominato r8 GB | XFX Radeon 6950 2 GB | Samsung 500 GB + 2x 160 GB | Corsair Force 120 GB || NAD C326BEE | Cerwin Vega VS-10 | LG LH4000| Samsung SyncMaster EX2220

Permalänk
Medlem
Skrivet av oscaralexiusson:

Just en relationsmodell jag behöver ja, och jag använder ID i min databas, men jag skrev inte med alla attribut!
Jag ville undvika att ha upprepning på alla produkter i tabellen, därför jag efterfrågade en annan design om det var möjligt!

jag skrev ut namnen för att det såg lite roligare ut än det här

Produkt | Ingrediens | Mängd | Enhet --------+------------+-------+------ 1 | 1 | 6 | 1 1 | 2 | 1 | 2 1 | 3 | 500 | 3 2 | 3 | 100 | 3 2 | 4 | 600 | 3 3 | 5 | 1 | 1 3 | 6 | 1 | 4 3 | 7 | 90 | 3

det är hur som helst samma lösnings-förslag som iXam lämnat.

Visa signatur

as far as we can tell, the massacre went well...

Permalänk
Medlem

Alltså, jag tycker egentligen inte att man behöver blanda in nummer för att göra det här "krångligare" än vad det behöver vara. Jag går själv C-programmet på LTH och läste precis databashantering (grundkurs) med Per Holm nu i period ett.

Anta att du har en tabell med produkter (PRODUCTS) och en med ingredienser (INGREDIENTS). En ingrediens kan ingå i många produkter, och en produkt kan ha flera ingredienser - du har alltså ett många-till-många-förhållande mellan dessa entiteter, och därför kan du införa en ny tabell/relation mellan de två, som heter typ "recipe" eller "contains" eller liknande.

Jag förutsätter att du vet hur primärnycklar och främmande nycklar (foreign keys) fungerar. Gör så att du i recipe/contains-tabellen tar kombinationen av ingrediensnamn och produktnamn till en gemensam primärnyckel, typ i stil med det här:

Create table recipe(
product_name varchar(50),
ingredient_name varchar(50),
amount int not null,
primary key (product_name,ingredient_name),
foreign key (product_name,ingredient_name) references (Products,Ingredients)
);

attributet amount används helt enkelt till att hålla reda på mängden av den ingrediensen du behöver i en given produkt.

Detta ska fungera, och det är på detta sätt vi löst det och fått godkänt av lärare.
Jag kan dessutom passa på att upplysa dig om att du efter värdena som utgör primärnycklar aldrig behöver skriva "not null"; eftersom att det är just primärnycklar får de inte vara null oavsett.

edit: dina tre sql-satser ska alltså se ut så här (korrigerade något stavfel, tog bort onödiga not-null, etc...:

Create table Products(
product_name varchar(50),
PRIMARY KEY(product_name)
);

Create table Ingredients(
ingredient_name varchar(50),
in_stock double not NULL,
last_ordered date not NULL, 
primary key(ingredient_name)
);

Create table recipe(
product_name varchar(50),
ingredient_name varchar(50),
amount int not null,
primary key (product_name,ingredient_name),
foreign key (product_name,ingredient_name) references (Products,Ingredients)
);

Visa signatur

Main Setup: Antec P193 | ASUS Crosshair IV Formula | AMD Phenom II X6 1090T @ 4.0 GHz | CORSAIR XMS3 8GB 1600MHz 7-8-7-20 | Powercolor 5870 PCS+ 1 Gb GDDR5 | Crucial RealSSD C300 128 Gb SATA3 | Samsung F3 HD103SJ 1000 Gb | Corsair AX 850W | Windows 7 Professional x64 |
Laptop: Acer Aspire 5740G | Intel Core i5-430M | 4 GB DDR3 1333 MHz | ATI Radeon HD5650 | Windows 7 Professional x64 |

Permalänk
Skrivet av Finess:

Alltså, jag tycker egentligen inte att man behöver blanda in nummer för att göra det här "krångligare" än vad det behöver vara. Jag går själv C-programmet på LTH och läste precis databashantering (grundkurs) med Per Holm nu i period ett.

Anta att du har en tabell med produkter (PRODUCTS) och en med ingredienser (INGREDIENTS). En ingrediens kan ingå i många produkter, och en produkt kan ha flera ingredienser - du har alltså ett många-till-många-förhållande mellan dessa entiteter, och därför kan du införa en ny tabell/relation mellan de två, som heter typ "recipe" eller "contains" eller liknande.

Jag förutsätter att du vet hur primärnycklar och främmande nycklar (foreign keys) fungerar. Gör så att du i recipe/contains-tabellen tar kombinationen av ingrediensnamn och produktnamn till en gemensam primärnyckel, typ i stil med det här:

Create table recipe(
product_name varchar(50),
ingredient_name varchar(50),
amount int not null,
primary key (product_name,ingredient_name),
foreign key (product_name,ingredient_name) references (Products,Ingredients)
);

attributet amount används helt enkelt till att hålla reda på mängden av den ingrediensen du behöver i en given produkt.

Detta ska fungera, och det är på detta sätt vi löst det och fått godkänt av lärare.
Jag kan dessutom passa på att upplysa dig om att du efter värdena som utgör primärnycklar aldrig behöver skriva "not null"; eftersom att det är just primärnycklar får de inte vara null oavsett.

edit: dina tre sql-satser ska alltså se ut så här (korrigerade något stavfel, tog bort onödiga not-null, etc...:

Create table Products(
product_name varchar(50),
PRIMARY KEY(product_name)
);

Create table Ingredients(
ingredient_name varchar(50),
in_stock double not NULL,
last_ordered date not NULL, 
primary key(ingredient_name)
);

Create table recipe(
product_name varchar(50),
ingredient_name varchar(50),
amount int not null,
primary key (product_name,ingredient_name),
foreign key (product_name,ingredient_name) references (Products,Ingredients)
);

Snällt med hjälp men det är fortfarande inte detta jag frågar efter! Jag kan databasgrunderna och vet precis hur man ska göra den tabellen du precis skapat.
Det jag undrade över är OM det går att utifrån en tabells VÄRDEN under ETT attribut skapa värdena som attribut i en ny tabell.

Visa signatur

MSI P67A-GD55 | Core i7 2600k @4.0 Noctua NH-D14| Corsair HX 650W | Corsair Dominato r8 GB | XFX Radeon 6950 2 GB | Samsung 500 GB + 2x 160 GB | Corsair Force 120 GB || NAD C326BEE | Cerwin Vega VS-10 | LG LH4000| Samsung SyncMaster EX2220

Permalänk
Medlem
Skrivet av oscaralexiusson:

Snällt med hjälp men det är fortfarande inte detta jag frågar efter! Jag kan databasgrunderna och vet precis hur man ska göra den tabellen du precis skapat.
Det jag undrade över är OM det går att utifrån en tabells VÄRDEN under ETT attribut skapa värdena som attribut i en ny tabell.

Jag är nog trött, har suttit på jobbet hela dagen, men jag förstår verkligen inte vad du menar.

Kan du exemplifiera hur du har det, och hur du VILL ha det?

Visa signatur

Jag är en optimist; det är aldrig så dåligt så att det inte kan bli sämre.

Permalänk
Medlem
Skrivet av Finess:

Alltså, jag tycker egentligen inte att man behöver blanda in nummer för att göra det här "krångligare" än vad det behöver vara. Jag går själv C-programmet på LTH och läste precis databashantering (grundkurs) med Per Holm nu i period ett.

Må hända inte behövas i små databaser men vist ibland behövs inte ID'n som nummer, ibland funkar text bra, I vissa fall funkar detta mindre bra.

Varför funkar detta mindre bra?

Först och främst, tänk på denna enormt stora extra datamängd du nu behöver. T.ex. har du längre namn som standard än 4 byte ( integer ) så kommer du behöva mer minne för att läsa och spara index som i sin tur kommer att ta betydligt mer prestanda o.s.v. Det blir ganska stora skillnader när datan växer.

Har du små korta tabeller där alla namn är Unika och finns inga produkter som t.ex. delar namn så vist funkar detta bra men det blir mer jobb att fixa om informationen växer, och det har en tendens att göra så i databaser.

I dagsläget är HD utrymme inte precis avgörande faktor varför man inte använder ID eller normaliserar mer en tredje graden men prestandan kan fortfarande vara en avgörande faktor.

---

Skrivet av oscaralexiusson:

Snällt med hjälp men det är fortfarande inte detta jag frågar efter! Jag kan databasgrunderna och vet precis hur man ska göra den tabellen du precis skapat.
Det jag undrade över är OM det går att utifrån en tabells VÄRDEN under ETT attribut skapa värdena som attribut i en ny tabell.

Attribut? Du snackar kolumner här antar jag, finns liksom inget som heter Attribut i SQL.

Och om det är det du snackar, hur du insätter data i en annan tabell baserat på en redan existerande data? I så fall gå tillbaka till dina grunder då detta är riktigt grundläggande och ser ut som du missat detta. I alla fall kasta din bok du sitter och läser då den värkar inehåller riktigt mycket felaktig fakta och köp denna istället.
Vist den är gjord för MsSQL men finns ingen bättre SQL bok på marknaden och den går igenom grunderna som även funkar i MySQL.
I alla fall till ditt problem.

INSERT INTO TABLE (SomeRandomColumn)
SELECT SomeOtherRandomColumn FROM othertable.

Du hittar mer om detta här för MySQL: http://dev.mysql.com/doc/refman/5.1/en/insert-select.html

Visa signatur

Speldator: i7-8700k, 32GB DDR4, RTX2080
Server 1: SB 2500k, MZI -P67GD55, 32GB DDR3, Corsair MX 240GB SSD
Surface Pro 2017, Konsoler: Typ alla, Oculus Rift

Permalänk
Skrivet av MugiMugi:

INSERT INTO TABLE (SomeRandomColumn)
SELECT SomeOtherRandomColumn FROM othertable.

Du hittar mer om detta här för MySQL: http://dev.mysql.com/doc/refman/5.1/en/insert-select.html

Jag vill inte sätta in värden i en redan existerande kolumn, jag vill lägga till kolumner som heter "värdena från den andra kolumnen"

Visa signatur

MSI P67A-GD55 | Core i7 2600k @4.0 Noctua NH-D14| Corsair HX 650W | Corsair Dominato r8 GB | XFX Radeon 6950 2 GB | Samsung 500 GB + 2x 160 GB | Corsair Force 120 GB || NAD C326BEE | Cerwin Vega VS-10 | LG LH4000| Samsung SyncMaster EX2220

Permalänk
Medlem
Skrivet av oscaralexiusson:

Jag vill inte sätta in värden i en redan existerande kolumn, jag vill lägga till kolumner som heter "värdena från den andra kolumnen"

Är det "alter table" du är ute efter? http://dev.mysql.com/doc/refman/5.1/en/alter-table.html

Permalänk
Medlem

Du vill alltså ha en kolumn för varje ingrediens? Om jag nu förstår dig rätt, I så fall har du redan här tänkt, fel du har fått svaret på hur du gör redan i andra inlägget i den här tråden.

Om jag fortfarande förstår dig fel så bör du visualisera vad du försöker göra, men förstod jag dig rätt så sluta upp på en gång då det är HELT fel sätt att gå till väga till problemet det är inte så man använder en relations databas och det bryter mot alla normaliserings former som finns.

http://www.databasteknik.se/webbkursen/normalisering/

Denna är läsvärd! Och har er lärare inte gått igenom normalisering har han missat något grovt.

Visa signatur

Speldator: i7-8700k, 32GB DDR4, RTX2080
Server 1: SB 2500k, MZI -P67GD55, 32GB DDR3, Corsair MX 240GB SSD
Surface Pro 2017, Konsoler: Typ alla, Oculus Rift

Permalänk
Medlem

Du kan i den tredje tabellen istället för att göra den till en relationstabell, lägga in värden med en separator, t.ex. semi-kolon. När du sedan läser upp värdet splittar du strängen på semi-colonet till en array, och gör sen lookupen på where id in array.

Det är dock lite hafsigt. Bättre att göra en riktig relation tycker jag.

Permalänk
Skrivet av MugiMugi:

Du vill alltså ha en kolumn för varje ingrediens? Om jag nu förstår dig rätt, I så fall har du redan här tänkt, fel du har fått svaret på hur du gör redan i andra inlägget i den här tråden.

Om jag fortfarande förstår dig fel så bör du visualisera vad du försöker göra, men förstod jag dig rätt så sluta upp på en gång då det är HELT fel sätt att gå till väga till problemet det är inte så man använder en relations databas och det bryter mot alla normaliserings former som finns.

http://www.databasteknik.se/webbkursen/normalisering/

Denna är läsvärd! Och har er lärare inte gått igenom normalisering har han missat något grovt.

Normalisering är inget krav, men då ska man kunna motivera varför man databasen inte är normaliserad! Min idé på tabellen kommer alltså inte vara normaliserad och den kommer inte heller innehålla någon primärnyckel!

Laddar upp en bild där jag beskriver hur jag vill att den ska se ut: http://tinypic.com/r/jr4gvn/6

Vill alltså utifrån vad som står under en kolumn (alla värden) skapa de värdenas namn som kolumner i den nya. Frågan är då om det går?

Om man kan ange att alla då ska vara, låt säga doubles då mängden är typen!

Visa signatur

MSI P67A-GD55 | Core i7 2600k @4.0 Noctua NH-D14| Corsair HX 650W | Corsair Dominato r8 GB | XFX Radeon 6950 2 GB | Samsung 500 GB + 2x 160 GB | Corsair Force 120 GB || NAD C326BEE | Cerwin Vega VS-10 | LG LH4000| Samsung SyncMaster EX2220

Permalänk
Medlem

Det där ser ut som en riktigt dum SQL uppbyggnad. Det är absolut inte så man bör bygga. Det är så man bygger när man inte vet. Lite som när ett barn ska bygga ett hus av klossar.

Visst kan du göra så om du vill, men det är riktigt riktigt fel på alla sätt.

Vad gör du om ett recept har 17 ingedienser? Hur gör du om vissa recept är i liter, andra i kilo? Vissa i nypor?

Permalänk
Medlem
Skrivet av oscaralexiusson:

Normalisering är inget krav, men då ska man kunna motivera varför man databasen inte är normaliserad! Min idé på tabellen kommer alltså inte vara normaliserad och den kommer inte heller innehålla någon primärnyckel!
Laddar upp en bild där jag beskriver hur jag vill att den ska se ut: http://tinypic.com/r/jr4gvn/6
Vill alltså utifrån vad som står under en kolumn (alla värden) skapa de värdenas namn som kolumner i den nya. Frågan är då om det går?
Om man kan ange att alla då ska vara, låt säga doubles då mängden är typen!

Då ska du nog inte använda en SQL-databas utan en så kallad NoSQL-databas. Där kan du vilt blanda in "kolumner".
Ett annat sätt är att serialisera ingridienserna och lagra dessa i EN kolumn i MySQL.
Postgresql stödjer columntypen array och där kan du göra det du vill med en enda kolumn OCH dessutom kunna söka i den.

Och om nu detta är en (skol)uppgift så ser jag ingen anledning till att prompt göra dumheter, det finns inget du vinner på detta annat än att visa upp att det är en dålig idé.

Permalänk
Skrivet av Ernesto:

Det där ser ut som en riktigt dum SQL uppbyggnad. Det är absolut inte så man bör bygga. Det är så man bygger när man inte vet. Lite som när ett barn ska bygga ett hus av klossar.

Visst kan du göra så om du vill, men det är riktigt riktigt fel på alla sätt.

Vad gör du om ett recept har 17 ingedienser? Hur gör du om vissa recept är i liter, andra i kilo? Vissa i nypor?

Har tänkt om lite nu och idén jag hade är som du påpekar inte bra!

Jag klarar mig alldeles utmärkt nu och tack för all hjälp!
Det jag egentligen bara ville veta är om det gick att göra det jag efterfrågade!

Visa signatur

MSI P67A-GD55 | Core i7 2600k @4.0 Noctua NH-D14| Corsair HX 650W | Corsair Dominato r8 GB | XFX Radeon 6950 2 GB | Samsung 500 GB + 2x 160 GB | Corsair Force 120 GB || NAD C326BEE | Cerwin Vega VS-10 | LG LH4000| Samsung SyncMaster EX2220