I have a question about a best practice approach regarding a one-to-many relationship using an MySQL-API, VueJS as a framework and a data-table using a JSON format.
I have a little example available here: https://codepen.io/rasenkantenstein/pen/MWYEvzK. This is a Vuetify data table which hosts information about desserts. One dessert can have many ingredients...
My problem is similar: I have a MySQL - membership table. In case of a family membership, one membership can relate to many people of the family. In a classic scheme I would have a membership table and a members table with a foreign key to the membership.
The membership table contains attributes such as a conctact adress, entry date etc. The members table contains attributes such as the name, birthdate etc. There are also transactions which also relate to the membership table among other things.
My approach is to try to hold all information in one membership table:
CREATE TABLE `Membership` (
`MembershipId` bigint(20) NOT NULL AUTO_INCREMENT,
`MembershipType` varchar(100) COLLATE latin1_german1_ci NOT NULL,
`MembershipMembers` json NOT NULL COMMENT 'contains a JSON String with family name, given name and birthdate',
`MembershipZipCode` int(11) NOT NULL, --and more attributes
However, two tables also seem feasable. Unfortunately, I wouldn't know how to update both tables with the JS-Axios-API inside the same data-table.
I am looking for some ressources to further help my decision making, e.g. links or certain keywords or hard advice.
Related
I'm going to keep it brief here for convenience's sake. I'm new to SQL coding, so please excuse me if I say something weird.
I did not manage to find a solid solution to it (at least one that I would truly understand), which is precisely why I'm posting here as a last resort at this point.
The table code:
create table companies (
company_id mediumint not null auto_increment,
Name varchar(40) not null,
Address varchar(40),
FoundingDate date,
primary key (company_id)
);
create table employees (
Employee_id mediumint not null auto_increment,
Name varchar (40),
Surname varchar(40),
primary key (Employee_id)
);
create table accounts (
Account_id mediumint not null auto_increment,
Account_number varchar(10) not null,
CompanyID int(10),
Date_of_creation date,
NET_value int(30),
VAT int(3),
Total_value int(40),
EmployeeID int(10) not null,
Description varchar(40),
primary key (Account_number)
);
Table values are random strings and numbers until I figure this out.
My issue is that I'm stuck at forming correct SQL queries, namely:
Query all accounts with their designated companies. I need it to show 'NULL' value if an account has no associated company.
Query that can list all accounts whose date is less than 2018-03-16 or those without a date.
Query that will print the description of the 'Accounts' table in one column and the number of characters in that description in a different column.
Query that lists all employees whose names end with '-gh' and that have names greater than 5 characters in length.
Query that will list the top total sum amount.
Query that will list all accounts that have '02' in them (i.e. 3/02/05).
If you can answer at least one of these queries and if you can explain how you got to the solution in a simplistic manner, well... I'm afraid I have nothing to offer but honest gratitude! ^^'
Welcome to the community, but as Jerry commented, you should really try to show SOMETHING that you have tried just to show what you THINK is needed. Also, don't just add comments to respond, but edit your original post with additional details / data as people ask questions.
To try and advance you forward though, I will point out two specific links that should help you out. The first one is a link for the basics on querying explaining the
select [fields] from [what table] join [other tables] where [what is your criteria] -- etc. Some Basics on querying
The next give some very good clarification on JOIN conditions of (INNER) JOIN -- which means required record match in BOTH tables being joined, and FULL OUTER JOINS, LEFT JOINs, etc.
After reviewing those, if you STILL have questions, please edit your original question, post some samples of what you THINK is working and let us know (or comment back to a specific answer), and we in the forum can follow-up with you.
HINT, your first query wanting NULL you should get from the visual link via LEFT JOIN.
A visual representation and samples on querying
I have a tables called userAccounts userProfiles and usersearches.
Each userAccount may have multiply Profiles. Each user may have many searches.
I have the db set up working with this. However in each search there may be several user profiles.
Ie, each user account may have a profile for each member of their family.
They then want to search and include all or some of their family members in their search. The way i would kinda like it to work is have a column in user searches called profiles and basically have a list of profileID that are included in that search. (But as far as i know, you can't do this in sql)
The only way i can think i can do this is have 10 columns called profile1, profile2 ... profile10 and place each profileid into the column and 0 or null in the unused space. (but this is clearly messy )
Creating columns of the form name1...nameN is a clear violation of the Zero, One or Infinity Rule of database normalization. Arbitrarily having ten of them is not the right approach, that's an assumption that will prove to be either wildly generous or too constrained most of the time. Since you're using a relational database, try and store your data relationally.
Consider the schema:
CREATE TABLE users (
id INT PRIMARY KEY AUTO_INCREMENT NOT NULL,
name VARCHAR(255),
UNIQUE KEY index_on_name (name)
);
CREATE TABLE profiles (
id INT PRIMARY KEY AUTO_INCREMENT NOT NULL,
user_id INT NOT NULL,
name VARCHAR(255),
email VARCHAR(255),
KEY index_on_user_id (user_id)
);
With that you can create zero or more profile records as required. You can also add or remove fields from the profile records without impacting the main user records.
If you ever want to search for all profiles associated with a user:
SELECT ... FROM profiles
LEFT JOIN users ON
users.id=profiles.user_id
WHERE users.name=?
Using a simple JOIN or subquery you can easily exercise this relationship.
I'm developing a classifieds site. And I'm totally stuck at database design level.
Advertisiment can only be in 1 category.
In my database I have table called "ads", which has columns, common for all advertisements.
CREATE TABLE Ads (
AdID int not null,
AdDate datetime not null,
AdCategory int not null,
AdHeading varchar(255) not null,
AdText varchar(255) not null,
etc...
);
I also have a lot of categories.
Ads that are posted in "cars" category, for example, have additional columns like make, model, color, etc. Ads, posted in "housing" have columns like housing type, sqft. etc...
I did something like:
CREATE TABLE Cars (
AdID int not null,
CarMake varchar (255) not null,
CarModel varchar(255) not null,
...
);
CREATE TABLE Housing (
AdID int not null,
HousingType varchar (255) not null
...
);
AdId in those is a foreign key to Ads.
But when I need to retrieve information from Ads, I have to look up all those additional tables and check if AdId in Ads equals to AdId in those tables.
For every category I need a new table. I'm gonna end up with like 15 tables or so.
I had an idea to have a boolean columns in Ads table like is_Cars, is_Housing, etc but having a 15 columns, where 14 would be NULL seems to be horrible.
Is there any better way to design this database? I need my database to be in a 3rd normal form, this is the most important requirement.
Don't worry too much - it's a well known dilemma, there are no 'silver bullets' and all solutions have some trade-offs. Your solution sounds good to me, and is commonly used in the industry. On the down side it has JOINS as you mentioned (which is a well-known trade-off of normalization anyway), and also each new product type requires a new TABLE. On the up side the table structure precisely reflects your business logic, it's readable and efficient in storage.
Your other suggestion, as far as I understand, was a single table where each row has a "type" indication - car, house etc (btw no need for multiple columns such as 'is_car', 'is_house' - it's simpler to have a single column 'type', e.g. type=1 indicates car, type=2 indicates house etc). Then multiple columns where some of them are unused for some product types.
Well, here the advantage is capability to add new types dynamically (even user-defined types) without changing the database schema. Also no 'JOINs'. On the down side you'll be storing & retrieving lots of 'null' cells, and also the schema would be less descriptive: e.g. it's harder to put a constraint "carModel column is not nullable", because it is nullable for houses (you can use triggers, but it's less readable).
Personally I prefer the 1st solution (of course depending on the usecase, but the 1st solution is my first instinct). And I can use it with some peace of mind after considering the trade-offs, e.g. understanding that I'm tolerating those JOINS as payment for a readable & compact schema.
One, you are confusing categories and product specifications.
Two, you need to read up on Table Inheritance.
If you don't mind nulls, use Single Table Inheritance. All "categories" (cars, houses, ...) go in one table and have a "type" column.
If you don't like nulls, use Class Table Inheritance. Make a master table with the primary keys that you point your category foreign key at. Make child tables for each type (cars, houses, ...) whose primary key is also a foreign key to the master table. This is easier with an ORM like Hibernate.
I have a web application where you can create a group. A group can be one of 3 options,
Organization
Client
Team
A client group and a team group are relatively simple, however the organisation is a little more complicated.
An organisation can have multiple clients, now my confusion is coming from how do I create this relationship, as the organizations, clients and teams are all saved in the same table. What is the best way to set this up? Should I create a client table that just contains a unique ID and the ID of each client in the groups table, and create a relationship between that and the groups table?
The way I understand it, your application requires hierarchical groups. In other words, Organization is a group but it also contains another group, such as Client. From your comments, it appears that you want to treat all three as groups.
I can suggest the following table:
entity
+ id INT UNSIGNED AUTO_INCREMENT
+ parentId INT UNSIGNED
+ type ENUM ('Client','Team','Organization')
+ name VARCHAR(255)
+ address VARCHAR(255)
For top-level entity such as an Organization, parentId will be zero. For a client/team group, parentId will refer to the id of an organization group. Actually, any kind of hierarchy is possible with the above definition.
If your columns for different groups need to be different, then you need multiple tables but one table can contain the group hierarchy as noted above.
I'm building a website where I will have users logging into the site from multiple sources, including Facebook and Google+ and I want to be able to keep some basic info on each user in my data base, so that I can track the creation of things like comments and posts. How do I efficiently do this in a SQL database. Do I create a new table for each type of user?
You just need two tables, a user table and a usertype table. The user table would have a column for type that would link to the usertype table and tell you the type. I would be something basic like this:
User (
Id Int NOT NULL PRIMARY KEY,
UserName VarChar(50) NOT NULL,
EmailAddress VarChar(100),
{... More fields generally used by all account types ...}
UserTypeId Int NOT NULL
)
UserType (
Id Int NOT NULL PRIMARY KEY,
Type VarChar(50) NOT NULL
)
If you have information that is specific to each log on type like Google+ or Facebook, you could create a table for each specific log on type. However, the reality is that you probably will get the same set of basic information fields for all of the different types possible so there is not much to worry about.
The usual approach is:
A USER table with the common data
A FACEBOOK_USER table (which has it's own PK and a USER FK) with the Facebook specific data
A GOOGLE_USER table...
When loading a user, you can join all those tables or you can create a view that contains the join or, if you have many special types, you can load the user and then read the others individually (maybe keep a IS_x_USER in the USER table to speed this up).