mySQL: unique constraint over three columns in conjunction with a specific value - mysql

Is it possible to create a unique constraint over three columns in mySQL, in conjunction with a specific value in one of the columns?
Example:
This is a table with links between a user (id 1000) and its properties
user_id, properties_id, value, active, date_add
1000, 1004, "011 23456", 1, 2020-08-11
1000, 1005, "Toyota", 1, 2020-08-11
1000, 1005, "Honda", 0, 2015-01-01
1000, 1005, "BMW", 0, 2002-01-01
The properties define the meaning of the column value:
1004 = Telephone number of the user
1005 = Car brand of the user
The user has already had 3 car brands in his life, so there are three entries with the properties ID 1005, one of which is active because this is his current car. The others are inactive.
I want to create a constraint that allows several combinations of user_id, properties_id and active, but only if active = 0. There must not be several identical properties that are all active.
(Even if a user can have several cars, he should always have only one current car in this data model).
Can mySQL map such a thing?
Greeting Markus

Related

Database Normalization For Table With Tree Like Data

How do I Normalize this table. It has a tree like structure which is expected to grow like a tree.
By tree like structure I mean that new students, subjects, levels and chapters will be constantly added or updated or removed
I want to store the result of a quiz in this table. the quiz has multiple subjects under which there are multiple levels under which there are mutliple chapter. and Every students can take different subjects.
So is this table good for storing the results or I need to do something with this table?
In this particular case you need to create several independent tables:
Table "Student"
ID, Name
1, John
2, Jack
Table "Subject"
ID, Name
1, Math
2, Science
3, Geography
4, History
5, English
Table "Levels"
ID, Name
1, Intermediate
2, Moderate
3, Difficult
Table "Chapters"
ID, Name
1, Chapter 1
2, Chapter 2
3, Chapter 3
And so on and so on.
Then you define the relations between the tables, like this:
Table "student_subject_level"
ID, student_id, subject_id, level_id
1, 1, 1, 1 (John, Math, Intermediate)
2, 1, 2, 2 (John, Science, Moderate)
So far you have the student, the corresponding subejct and the subject's level. Since we may have multiple chapters for each level, we need another relation:
Table "student_subject_level_chapter" (or use simpler name)
student_subject_level_id, chapter_id
1, 1 (John, Math, Intermediate, Chapter 1)
1, 2 (John, Math, Intermediate, Chapter 2)
2, 1 (John, Science, Moderate, Chapter 1)
And so on and so on. Start by isolating the individual tables and then figure out how you'd like to achieve the actual relation. Fore each new relation where you have redundant data, you'd like to have new table which keeps the relation you need. It's much easier once you have ID's to refer to, so start with the individual tables and figure your way through.

How would I store multiple values for one set of information for a specific user in MySQL?

So I have a set of data.
Let's say the user "Jim" likes the video games with IDs 5, 15, 30, 60, and 25.
Every user in the database gets one row in a table to store information. For example, the row may include separate fields including the user's display name, age, and the date that person was active last.
Now, let's say the website Jim is on is about video games. The website has a list of games that person can say he or she likes to play, in with their own unique ID. What is the is the best way I would store that information and relate that to the user without having to store a list of the game IDs in one field?
Three tables, one being a table of relationships between Games and Users:
Users (UserID, DisplayName, Age, LastActiveDate)
GamesLiked (UserID, GameID)
Games(GameID, GameName, etc)
GamesLiked would have 5 rows for Jim:
UserID GameID
1 5
1 15
1 25
1 30
1 60

database primary key based on variable number of customer subdivisions

Doing this in Groovy/Grails and GORM with a MySQL DB.
When storing data for our different customers we need to be able to identify their subdivisions. Some will have 0 levels of subdivisions. Some, 1, 2, 3, levels etc. We'd like to allow any number of levels of subdivisions, but could settle for a fixed number, such as 5, 7 or 10.
For instance:
Company ABC has 2 subdivision levels:
Company) ABC (the root level)
Subdivision Level 1) ABC->Div1, ABC->Div2, ABC->Div3
Subdivision Level 2) ABC->Div1->SubDiv1, ABC->Div1->SubDiv2, ABC->Div1->SubDiv3
Company DEF has 1 levels:
Company) DEF (the root level)
Level 1) DEF->Div1, DEF->Div2, DEF->Div3
We need to define both 1 to 1 and 1 to many unique attributes for each level (for example associate an address with ABC->Div1->SubDiv3)
And Company ABC may want us to display a certain image for all instances for Div2 and all of Div2's subdivisions.
The question is, how is it best to create a variable number of division levels for an identifier or primary key to then use as a foreign key on related data?
Have a fixed number of columns (like 7 and a complex key):
ID-Level-1, ID-Level-2, ID-Level-3, ID-Level-4, ID-Level-5, ID-Level-6, ID-Level-7
Or, create some sort of a tree of hierarchical levels and use the various key values as identifiers/foreign keys?
You could model this like the following
class Company {
static hasMany = [subdivisions: Subdivision]
}
class Subdivision {
static belongsTo = [company: Company, subdivision: Subdivision]
static hasMany = [subdivisions: Subdivision]
}
Store it just like you described: Company->Div->Subdiv:
id subdivision_name subdivision_level subdivision_path
-----------------------------------------------------------------
1 ABC 0 ABC
2 Div1 1 ABC->Div1
3 Div2 1 ABC->Div2
4 Div3 1 ABC->Div3
5 SubDiv1 2 ABC->Div1->SubDiv1
6 SubDiv2 2 ABC->Div1->SubDiv2
7 SubDiv3 2 ABC->Div1->SubDiv3
8 DEF 0 DEF
9 Div1 1 DEF->Div1
10 Div2 1 DEF->Div2
11 Div3 1 DEF->Div3
Number of levels is only limited by length of subdivision_path - standard datatypes should be more than enough.
So let's associate an address with ABC->Div1->SubDiv3:
CREATE TABLE addresses (id ... , subdivision_id INTEGER, ...);
ALTER TABLE addresses ADD CONSTRAINT fk_addresses_subdivisions FOREIGN KEY (subdivision_id) REFERENCES subdivisions (id);
... query all instances for Div2 and all of Div2's subdivisions.
SELECT * FROM subdivisions WHERE subdivision_path LIKE 'ABC->Div2%';
... for all subdivisions of Div2:
SELECT * FROM subdivisions WHERE subdivision_path LIKE 'ABC->Div2->%';
... for all root companies:
SELECT * FROM subdivisions WHERE level = 0;
... and more.
Alternatively subdivision_path can store ids, not names (maybe it's even better).

Union Query -> Pick One When Duplicate Value in Jet

I'm using Access to fill in details in a database across 3 offline computers. This means they all have a copy of the database, do a day of info filling, then get manually uploaded to a central database. Horrid, but it's the only option.
I have a pre-filled database, key identifiers etc are all determined previously; we are adding information to the blank fields for these entries. (Started with 3 key fields, added a few info fields). The user selects an entry and edits it rather than creating one. I then use a script which takes each table and unions the three databases into a table for each. The users do not duplicate work (meaning you don't have Jack working on entry A as well as Jill working on entry A).
My question: How can I get my union query to select all entries, even the unfilled ones, but let the filled ones take precedence? (aka bypass the "duplicate entry" error by choosing the filled in entry instead of the two unfilled entries?)
ex:
JOHN's DB JACK's DB JILL's DB ---> MASTER DB
A: 1, 1, __ 1, 1, __ 1, 1, "Yes" 1, 1, "Yes"
B: 1, 2, "No" 1, 2, __ 1, 2, __ 1, 2, "No"
C: 1, 3, __ 1, 3, __ 1, 3, "No" 1, 3, "No"
Completely terrible way to do this (Unioning offline tables, that is) but we have little other choice due to many other uncontrollable factors.
How about
SELECT Id, Max(Field)
FROM ( Select Id, Field FROM John
Union All ...)
GROUP BY Id

Best way to store arrays of variable length in MySQL

I want to make an app that allows users to add other users to a personal friendslist. In my database there is a table called 'users'. Every user has a unique id and a unique username, now every user needs to be able to have a list of friends.
I think the best option to save these friendslists is to create a seperate table with two colums, for every user. One column for the friends' id's and one for their usernames.
I can search and retrieve the friends username and id at the same time. On the downside I will need to create a hugh number of tables (hundreds, thousands, perhaps millions), one for each user.
Will this make selecting a table from the database slow?
Will this unnecessarily cost a hugh amount of space on the server?
Is there a better way to save a friendslist for every user?
You should not do that.
Instead do something like
UserTable
* Id
* UserName
FriendsTable
* UserId
* FriendId
You may need to read a little about relation databases.
This way a user can be friend to a lot of people. Consider for this example
UserTable
1, Joey
2, Rachel
3, Chandler
4, Ross
5, Phoebe
6, Monica
FriendTable
1, 2
1, 3
1, 4
1, 5
1, 6
2, 3
2, 4
2, 5
2, 6
3, 4
3, 5
3, 6
4, 5
4, 6
5, 6
Here the people from Friends is all friends to eachother
I don't think you need to go down that route. If you have a table of users (user_id, user_name) for example and another table of friendships (friendship_id, user_id1, user_id2) then you will be able to store all friendships in one table. The unique id being friendship_id.