I have 2 table:
Movie
movie_id
Stuff
staff_id
staff_name
crew_role_id
where crew_role_id - FK with static data(ex. director, actor etc.)
Also I have table movie_crew, which is just many-to-many table:
staff_id
movie_id
But in case the staff is an actor, I need add additional information who he plays(character_name) and what role he has(character_type)
So, we have another many-to-many table movie_cast like this
staff_id
movie_id
character_name
character_type
But it looks bad and hard to implement(don't repeat code).
The best solution I have is to add id to movie_crew, movie_crew_id, and then add this id to movie_cast. But I'm afraid that due to many unique id in movie_crew, we will have poor performance and so on. Are there better solutions?
I use MySql, Java(Hibernate)
I'm very new to SQL and I want the contracts_tb (query details below) is to display and link the foreign id keys referred from:
med_idref (referred from med_id (INTEGER), PRIMARY KEY o mediaadv_tb),
mediatitle_ref (title (TEXT), mediaadv_tb),
mediatype_red (mtype (TEXT), mediaadv_tb),
cus_idref (cus_id (INTEGER),PRIMARY KEY of customer_tb),
cus_companyref (referred from company (TEXT), in customer_tb)
All to be linked and displayed to contracts_tb. When I add/replace values from mediaadv_tb and customer_tb, I get this problem:
foreignkey mismatch
Also, do I have to make or assign a parent table?
Query:
DROP TABLE IF EXISTS customer_tb;
CREATE TABLE IF NOT EXISTS customer_tb (
cus_id INTEGER PRIMARY KEY,
company TEXT,
firstname TEXT,
middlename TEXT,
lastname TEXT,
gender TEXT,
dob TEXT,
dateregistered TEXT,
contactno TEXT,
emailaddress TEXT,
description TEXT,
refpic INTEGER,
cuspic BLOB
);
DROP TABLE IF EXISTS mediaadv_tb;
CREATE TABLE IF NOT EXISTS mediaadv_tb (
med_id INTEGER PRIMARY KEY,
mtype TEXT,
duration TEXT,
title TEXT,
dateadded TEXT,
desription TEXT,
previewimg BLOB,
filepath TEXT
);
DROP TABLE IF EXISTS contracts_tb;
CREATE TABLE IF NOT EXISTS contracts_tb (
contract_id INTEGER PRIMARY KEY,
customer_idref INTEGER REFERENCES customer_tb (cus_id),
media_idref INTEGER REFERENCES mediaadv_tb (med_id),
media_typeref TEXT REFERENCES mediaadv_tb(mtype),
media_titleref TEXT REFERENCES mediaadv_tb (title),
status TEXT,
priority TEXT,
dateadded TEXT,
dateexpiration TEXT,
amountpaid REAL,
arearofcoverage TEXT
);
Error :-
contracts_tb
mediaadv_tb
I believe that your issue is because the foreign keys defined that reference the media_typeref and the media_titleref columns are invalid as they do not have, or are part of a, UNIQUE indexes (no indexes). SQLite Foreign Key Support - 3. Required and Suggested Database Indexes
The referenced id columns, as they are INTEGER PRIMARY KEY, are implicitly UNIQUE indexes.
Furthermore the two columns (typeref and titleref) themself aren't even needed as the media_idref column would be used to identify the reference and thus would hold the respective values. Copying those values into the contracts table would be contrary to normalisation and may even create major headaches (e.g. if a value changed you'd have to find all other uses and also change them).
As such I'd suggest that the contracts_tb be created using :-
DROP TABLE IF EXISTS contracts_tb;
CREATE TABLE IF NOT EXISTS contracts_tb (
contract_id INTEGER PRIMARY KEY,
customer_idref INTEGER REFERENCES customer_tb (cus_id),
media_idref INTEGER REFERENCES mediaadv_tb (med_id),
status TEXT,
priority TEXT,
dateadded TEXT,
dateexpiration TEXT,
amountpaid REAL,
arearofcoverage TEXT
);
Re comment :-
What i'm making is a Java NetBeans SQLite database program, where by
using the Contracts frame, whevenr one makes a new contract, there
will be a combobox that restricts the user to only put the existing
ids or names that is referred in the contracts_tb then provides the
choices. Is it possible sir?
Yes.
More specifically:-
Assume that you have customers Fred, Bert and Harry (id's 1,2 and 3 respectively). And that you have mediaadv's M1, M2 and M3 (id's 10,11 and 12 (not 1,2 and 3 to help distinguish between mediaadv and customers)).
Additionally I'll assume the suggested contracts_tb table as opposed to the original in the question (i.e. 2 columns dropped as suggested)
The when inserting a new contract, you present a list (combobox) of the customers e.g.
Fred
Bert
Harry
(this list could be generated from a query such as:-
SELECT cus_id,firstname FROM customer_tb; i.e. all existing customers)
If you wanted Fred James Bloggs then you could use :-
SELECT cus_id,firstname||' '||middlename||'lastname' AS fullname FROM customer_tb;.
Likewise a list of the existing mediaadv could be generated from a query such as:-
SELECT med_id, description FROM mediaadv_tb; e.g.
so the combobox would have:-
M1
M2
M3
Now if the contract were for Bert (id 2) and M1 (id 10) then you build SQL something like :-
INSERT INTO contracts_tb VALUES(null,2,10,'the_status','the_priority','yyyy-mm-dd','yyyy-mm-dd',500,'the_coverage');
1st value is null i.e. no value, so as contract_id is an alias of the rowid it will be generated.
2 is the id of the customer (hence why cus_id was in the query as you need the id as it's the value you are going to store)
10 is the id of the mediaadv (again hence why med_id was in the query as you need the id as it's the value you are going to store).
the other values are what they should be.
Note the above use of INSERT requires that all columns be given. You can skip columns by specifying a list of the columns e.g. INSERT INTO contracts_tb (customer_idref,media_idref) VALUES(2,10);
As a customer with an cus_id of 2 (Bert) exists then the constraint that customer_idref is an existing id in the customer_tb is good/met and there is no conflict.
Likewise as there is a row in mediaadv_tb that has an med_id of 10 this constraint is good/met and there is no conflict.
However say the SQL were :-
INSERT INTO contracts_tb VALUES(null,2,100,'the_status','the_priority','yyyy-mm-dd','yyyy-mm-dd',500,'the_coverage');
Then as there is no med_id of 100 the constraint saying that media_idref must reference a value of 100 (in this instance) in the mediaadv_tb, column med_id, then the constraint will not be met and the insert will fail.
So again Yes, I believe that what you want is feasible.
Note a foreign key is only a constraint it doesn't bind/associate columns or join tables.
Using MySQL, I have the following SQL Table definition:
CREATE TABLE books (
author INT,
book INT,
name VARCHAR(128),
PRIMARY KEY(author, book)
);
What I want is that I have an Id for author that I set manually and an Id for book that is incremented for each author id. Therefore I created a trigger like so:
CREATE TRIGGER trBooks
BEFORE INSERT ON books
FOR EACH ROW SET NEW.book = (
SELECT COALESCE(MAX(book), -1) + 1 FROM books
WHERE author = NEW.author
);
This works fine for me. But now I need to know the book id that was set for my inserted entry that I inserted in Java. Something like the Insert with Output as in MSSQL or a Statement.executeQuery("INSERT ..."). The solution has to be thread safe, so a separate INSERT and SELECT is no good solution, since there might have been another INSERT in the meantime.
Thanks for your help!
Your data model just doesn't make sense. You have two entities, "books" and "authors". These should each be represented as a table. Because a book can have multiple authors and an author can write multiple books, you want a junction table.
This looks like this:
CREATE TABLE Books (
BookId INT auto_increment primary key,
Title VARCHAR(255)
);
CREATE TABLE Authors (
AuthorId INT auto_increment primary key,
Name VARCHAR(255)
);
CREATE TABLE BookAuthors (
BookAuthorId INT auto_increment primary key,
AuthorId INT,
BookId INT,
CONSTRAINT fk_BookAuthor_BookId FOREIGN KEY (BookId) REFERENCES Books(BookId),
CONSTRAINT fk_BookAuthor_AuthorId FOREIGN KEY (BookId) REFERENCES Authors(AuthorId),
UNIQUE (AuthorId, BookId)
);
As for your question about inserts. You don't need a trigger to set auto-incremented ids. You can use LAST_INSERT_ID() to fetch the most recent inserted value.
I bought the deitel java how to program book. I am following one of their exercises.
In my program I am connected to a mysql books database. I was able to add a new author, edit author, new title. However, part d) is confusing to me. Am I suppose to alter the table and add a foreign key?
Here are the exercises from the book so you can see part d)
a) Add a new Author
b) Edit the existing information for an author
c) Add a new title for an author (Remember that the book must have entry in the AuthorISBN table.)
d) Add a new entry in the authorISBN table to link authors with titles.
Here is a screen shot of the database open in "toad"
If they mean to write a sql statement would I add a new AuthorID with a reference to title?
ALTER TABLE AuthorISBN ADD FOREIGN KEY (AuthorID) REFERENCES title (AuthorID);
You are not supposed to alter the table. I assume they have given you the structure of the tables (the screenshot) and you are supposed to add new entries in all parts of the exercise. In d) they want you to add an entry to the table AuthorISBN, so that two entries in Author and Title are logically connected.
AuthorISBN consists of two data fields. AuthorID and ISBN are foreign keys, so for every entry in the table AuthorISBN there has to be an adequate entry with the same AuthorID in the table Authors and a an entry with the same ISBN in Titles.
So in a) you add an author. The AuthorID is automatically incremented, so you have to retrieve the ID after you inserted the author. In c) you add a book by this author. But how you know later, which author wrote a specific book? Or you want to retrieve a list of all book by an author. Thats why you add in d) an entry to AuthorISBN.
So with JDBC you would do something like this:
Statement stmt = connection.createStatement();
String sql = "INSERT INTO AuthorISBN VALUES (" + authorID + ", '" + isbn + "')";
stmt.executeUpdate(sql);
We have the following (poorly designed?) table:
inputs:
keyword_id serial not null,
group_name string not null,
banned_term string not null
Keyword ID is the primary key. there are many banned terms per group_name. The data looks like this:
keyword_id | group_name | banned_term
1 | incentivization | free money
2 | inaccuracy | we're number one
3 | incentivization | win a free ipod!
There's no join table, and group_name isn't its own entity. I'd like a domain object something like this:
class BannedTermGroup {
Integer id;
String group_name;
Set<String> banned_terms;
// ... various getters and setters
}
The only examples on this one-to-many relationship between the group name and banned terms all involve some sort of join column or join table, while group_name would always be part of some other entity. Here neither is the case. Can this be mapped using Hibernate?
As quoted in my previous comment, you can get the ID of the group from nowhere.
Just to put aside this problem, you may look into Hibernate's reference, search for collections of basic types. It is what you need.
However, you still need to have a table for the "group".
assume it is as simple as a one column table:
KEYWORD_GROUP
--------------------
GROUP_NAME STRING
Your original keyword table:
KEYWORD
--------------------
GROUP_NAME STRING
KEYWORD STRING
I believe this is what you need:
#Entity
#Table("KEYWORD_GROUP")
public class KeywordGroup {
[.....]
#ElementCollection
#CollectionTable(name="KEYWORD", joinColumns=#JoinColumn(name="GROUP_NAME"))
#Column(name="KEYWORD")
private List<String> keywords;
}
For the keyword_group table, you probably don't need to create a new table if you are just using this model for read. Create a view from your original keyword table should be good enough.