I've an endpoint /user which creates an unique UUID for a user. It inserts the data(phoneno, gender, age) into the table(cassandra table) and then forwards the same data to another server along with the user_id just created, having MYSQL as the DB.
Now in my MySQL the table is as follow.
id(varchar)
phone no
age
gender
etc.
But I've read that using VARCHAR as PK is a very bad solution. Hence I modified my table as follow:-
id(interger auto increment)
user_id (varchar unique)
phone no
age
gender
etc.
I have another endpoint /recharge, which contains the user_id (UUID), recharge_amount, operator, etc..
My recharge table is as follow:-
user_id FK
amount
operator
Now the problem arises that whenever I'll receive the data for /recharge I need to get the respective id of the user from the Users table to reference it in the recharge table, which is an extra operation. ie for every insert, there will be an extra read operation.
Can I reference/use the unique key as my FK in the recharge table. If no, then what can be the possible solution?
Yes, you can use unique key as foreign key.
To use a column as FK in other table it has to be a PK or a Unique Key.
Related
Im new to building databases and have seen both examples of using and ID field or changing the field to a related name such as user_id is this just preference?
I guess it's a matter of personal taste. What I've come to find useful is to name the ID column id, but in tables where this is a foreign key, name it table_id.
For example, the ID column in the users table could be named id, but the foreign key in the table that assigns user rights to users it would be users_id to make clear that this is a reference to the users table.
What I am trying to do is set up the database table so that a set of multiple attributes must be unique but can be put in the database as many times as possible. For example if I had the following information with ID as the primary key:
id email name value
1 a#gmail.com A AValue
2 a#gmail.com A BValue
3 b#gmail.com B CValue
I don't want to have
id email name value
4 a#gmail.com B yetAnotherValue
combination possible where the email is to a different name. I want it to throw an exception. Is there any way to do this without a trigger or creating a separate table. If not , why not? Thank you.
Your question implies that name should be "dependent" on email. As such, your schema violates 3NF and, absent good reason, should be avoided: instead, you should have a table of (email, name) pairs with a UNIQUE constraint defined over the email column (and another over the name column, if the same name cannot be associated with multiple email addresses):
CREATE TABLE email_names (PRIMARY KEY (email))
AS SELECT DISTINCT email, name FROM your_table
Then your data table should simply contain a foreign key into this new table:
ALTER TABLE your_table
DROP COLUMN name,
ADD FOREIGN KEY (email) REFERENCES email_names (email)
To retrieve the names with your data, you would need to join the tables together in the relevant SELECT statement:
SELECT o.id, o.email, n.name, o.value
FROM your_table AS o JOIN email_names AS n USING (email)
However, there are sometimes good reasons for using denormalised schema—often when performance concerns are at play—and constraints of this nature can be enforced in MySQL. Before citing "anticipated" performance concerns, one should be mindful of Knuth's maxim that "premature optimisation is the root of all evil", and that the above approach will be very performant due to the indexing employed. Nevertheless, to enforce this constraint in your existing table:
Create a composite index over the combined columns in the table created above:
ALTER TABLE email_names
ADD INDEX (email, name)
Then, instead of the above changes to your current table, define a composite foreign key into the new table:
ALTER TABLE your_table
ADD FOREIGN KEY (email, name) REFERENCES email_names (email, name)
I'm creating a system that involves uploads. Now these uploads need to be attached to one of a manner of things eg. a message, a contract, a project
Is it okay to have one table for attachments then link them to these types - the caveat being that it needs to be linked to an individual id from each of these types
eg. in the attachment table
type - links to a table with the list of message contract etc
id. - an id # of what ever id for the type so if the type is message then it would refer to message.id if it was a contract it would refer to contract.id
but then there's no foreign key checks? But it seems odd to have to do foreign keys eg.
type
message_id (FK)
contract_id (FK)
project_id (FK)
Edit: there's a few more tables than 3 more like 5-6 perhaps more in future too..
I would recommend:
A table for attachment (attachment_id + other columns necessary for your attachment)
For each possible types (message, contract, project), you will have a relationship table.
Example:
MessageAttachmentTable: message_id (FK), attachment_id (FK)
ContractAttachmentTable: contract_id (FK), attachment_id (FK)
That way, you can have all the database integrity constraints with no unused columns.
Three NULLable fields with foreign keys to the respective tables is in my opinion the most sensible approach.
Moreover, if you have three foreign key fields, you don't even have to store the "type", since it is determined by the foreign key field which is not NULL.
I want two tables to share a primary auto incrementing id, is this possible? how do i do this? is their anything i need to consider?
the reasons i am doing this, is because it is a better solution than adding groups column to the users table, and also better than creating a completly seperate groups table, because if they share a primary key, i can use the existing posts table for both groups and users. instead of having to create a two distinct posts tables, (group_posts table for group posts. and a user_posts table for user posts.)
existing users table is
id(primary, ai)
username
password
email
my groups table that i want to link to my users table with a shared ai primary key
id(primary, ai, linked to users table id)
group_name
created_by
creation_date
etc.
You should make you schema clearer by doing the following:
Create a table (e.g. people)
id, primary key, auto-increment
type, tells you if it's a user or a group
Make users and groups primary keys foreign keys on people
Insert records in people
Obtain the ID that was assigned using LAST_INSERT_ID()
Insert in users or groups appropriately, using the ID obtained above
Then you'd reference "people", and not "users" or "groups" in your posts table and so on.
Conceptually, thinking of it in an OO way, it means users and groups both extend people.
I have two tables that need to be related--a users table and an address_book table
I want each address book entry to be associated with a user_id so that when I delete a user, their address book entries get deleted. But I also have about 10000 entries in the address book that are shared among all users. The user id field for each of those entries is set to 0. There is no user with an id of 0. MySQL won't let me create a foreign key for that field if there's a broken child/parent relationship there. How would I go about setting a foreign key in the address_book table for all users except with an id of 0?
have the user_id of the shared addresses be NULL instead of 0.