Are there any naming conventions for self-referential, many-to-many relationship tables? - sql

Let's say we have a table called Users for a fictional social media platform. In addition to regular users, some more experienced users are asked to be "greeters" where they are assigned other, newer users to greet and encourage. Because greeters aren't always available, multiple greeters are assigned to each new user and each greeter is assigned multiple new users.
Thus we have a self-referential, many-to-many user relationship we need a link table for.
Are there any conventions for this case?
Here are some ideas based on conventions I've found for standard many-to-many tables:
user_user: doesn't tell us much and there might be more than one relationship like this
Greeters: (i.e. use a new name that describes the relationship) pretty good, but it doesn't communicate that it's a link table or related to Users
greeter_user: (use a different name for one part of the relationship)
What do you use or what would you recommend?

In the entity–relationship model this would be modeled as user encourages user.
This could be translated into the tables Users and Encouragements.
CREATE TABLE Users (
username VARCHAR(32) PRIMARY KEY,
...
);
CREATE TABLE Encouragements (
greeterName VARCHAR(32),
newbieName VARCHAR(32),
PRIMARY KEY (greeterName, newbieName),
FOREIGN KEY (greeterName) REFERENCES Users(username),
FOREIGN KEY (newbieName) REFERENCES Users(username)
);
https://en.wikipedia.org/wiki/Entity%E2%80%93relationship_model

Related

postgreSQL/PostGIS database: Table inheritance

I am relatively new to postgreSQL and database design, and am currently puzzling with the method of INHERITANCE and whether it is relevant or appropriate to apply it to some of the tables in the postgreSQL/
PostGIS database I am currently creating. I would greatly appreciate any advice.
The three table scenarios I am unsure about are presented below:
1)
The first case is an ecology table that holds information about flora and fauna (see below). All the attributes, except the resourceGroup and name attributes, takes the same types of input values
regardless of whether the record refers to flora or fauna. The values that goes in the resourceGroup and name, refer to values from different lookup tables that are specific to either fauna or flora.
CREATE TABLE "ecology" (
"ecology_id" serial NOT NULL,
"resourceType" varchar(5) # ie. flora, fauna
"resourceUse" varchar(20) NOT NULL,
"resourceGroup" varchar(20) NOT NULL # takes input from different lookup tables depending if it is flora (ie. roots, seeds...) or fauna (ie. mammal, reptile ..)
"native" boolean NOT NULL,
"name" varchar(30) NOT NULL, # ie species name
"englishName" varchar(30) NOT NULL,
"NTStatus" varchar(20) NOT NULL,
"description" varchar(255) NOT NULL,
CONSTRAINT "ecology_pk" PRIMARY KEY ("ecology_id")
);
Question: Is inheritance the answer here, ie.
CREATE TABLE "fauna" (
"faunaGroup" varchar(5)
"name" varchar(30) NOT NULL,
"englishName" varchar(30) NOT NULL) INHERITS(ecology);
..and similar for flora, and then remove those attributes from the ecology table. Or is there a way to specify a constraint on the ecology table that when resourceType is
set to ie. flora, then the input values in the resourceGroup and name fields are restricted to the lookup tables that refer to respectively flora name and flora group, and vise versa?
2)
The other potential Inheritance table scenario refers to the table documentation. This table stores information on and urls to different types of documentation methods, ie. reports
AV, images, forms ect. The problem here is that some of the documentation types, such as reports and AV, share a many-to-many relationship with another main entity, while ie.
images and forms are one-to-many. Besides this they share the same type of attribute information
Question: is inheritance the way to go to account for the different types of relationships, or should I just group them all together in one table (documentation) and treat all as a many-to-many relationship?
3)
This table scenario concerns certain tables that stores culturally sensitive information. There are essentially three access restrictions to some of the attributes in these
tables: public, men only, and women only.
Question: Again could inheritance be the way forward here. Ie. creating two child tables for respectively men and women, that inherits all or some of the attributes from the parent
table. You could then ecrypt respectively the men and women child tables? Or alternatively, would a simpler or better solution be to account for
the gender and public restricted access at the schema level. So ie. creating respectively a men and women schema and group roles for each work type (ie ranger work, planning, ect ), as well as a schema that
stores information that is open to the public.
Thanks in advance.
Best
Ric.
ecology / fauna / flora:
I think that inheritance is a possible way to model that. You seem to have got the table definitions wrong though: the ecology table should have the attributes that both fauna and flora have, and you only specify those rows in the inheritance children that are added.
documentation:
That could also work with inheritance. Since all inheritance children are tables in their own right, they can have foreign key constraints with other tables.
information visible to men or women:
That cannot be modeled well with inheritance. If you want to restrict visibility to table rows based on the database role, look into Row Level Security.

SQL tables design layout

I'm trying to design my database with very basic tables and I am confused on the CORRECT way to do it.
I've attached a picture of the main info, and I'm not quite sure how to link them. Meaning what should be a foreign key, or should some of these tables include of LIST<> of the other tables.
UPDATE TO TABLES
As per your requirements, You are right about the associative table
Client can have multiple accounts And Accounts can have multiple clients
Then, Many (Client) to Many (Account)
So, Create an associate table to break the many to many relationship first. Then join it that way
Account can have only one Manager
Which means One(Manager) to Many(Accounts)
So, add an attribute called ManagerID in Accounts
Account can have many traedetail
Which means One(Accounts) to Many(TradeDetails)
So, add an attribute called AccountID in TradeDetails
Depends on whether you are looking to have a normalized database or some other type of design paradigm. I recommend doing some reading on the concepts of database normalization and referential integrity.
What I would do is make tables that have a 1 to 1 relationship such as account/manager into a single table (unless you can think of a really good reason not to). Add Clientid as a foreign key to Account. Add AccountID as a foreign key to TradeDetail. You are basically setting up everything as 1 to many relationships where the table that has 1 record for the id has the field as a primary key and the table that has many has it as a foreign key.

How can I make this column an unique column

I have many applications. Each applications can have many languages assigned.
For each language there can be many translations.
Each translation has a Key column which is the primary key.
When 2 applications create a translation with Key = "AdminAreaTitle" there will be a duplicate key exception. I know this will rarely happen. But getting an exception that another application has this key already sounds pretty bad user experience.
What I want is a translation key per application so the primary key of translation would be Key and I guess ApplicationName.
How would you extend the design to get that behavior?
Removed wrong image!
UPDATE
This is now a sql view on the tables/relations not entity framework view anymore.
WITH surrogate keys
UPDATE 2
WITH natural keys
I must say I prefer this ERD more because its simpler to design and think about. The surrogate key is more disturbing.
UPDATE 3
I created a new database with 3 tables and all natural keys see the screenshot, but I keep getting an error message from sql management studio:
The ERD you show is broken, because you show tables with their primary keys plus their relations (1:n, n:m) and these do not match. The keys of application and language suggest 1:n, but your graphic is labeled n:m.
What you might have now is something like (PK bold):
application (app_name)
application_language (app_name, iso_lang)
translation (key, iso_lang, text)
But you want each application to define their own texts, so add the app_name to your composite PK for the translations table.
application (app_name)
application_language (app_name, iso_lang)
translation (key, app_name, iso_lang, text)
In the E-R model, your database is described with two tables (Application) and (Language), and a relationship (Translate) between them (entities are "nouns", and relationships are "verbs").
In a real DBMS, a relationship is a table that contains both the two primary keys of a certain application that is being translated in a certain language (and other characteristics proper of the traslation itself), making the relationship unique (an application may be translated in many languages, and a language can translate many applications, but an application may be translated only once in french).
APPLICATION
AppName (PK)
...
LANGUAGE
LangName (PK)
...
TRANSLATE
AppName (PK)
LangName (PK)
...
Instead of storing the language in the translation table, you should store the identity of the relation between the application and the language. That way the translations will be unique to the language for that application instead of just for the language.
As the application name seems like information that might change (not in meaning but in how they are described), I suggest that you use a numeric key for it.
Something like:
Application
ApplicationId int, identity, pk
ApplicationName nvarchar(50)
ApplicationLanguage
ApplicationLanguageId int, identity, pk
ApplicationId int
LanguageId int
Language
LanguageId int, identity, pk
LanguageName nvarchar(50)
Translation
ApplicationLanguageId int, pk
Key nvarchar(20), pk
Text nvarchar(max)

What are the benefits of using separate role-bridge table over all-in-one table?

I have a bridge table book_person between tables book and person to provide many-to-many relation. In this table I also have role-definitions, to set which roles (author, editor, illustrator, translator etc.) a person has on particular book. Now I consider to split roles to separate role tables (like book_author, book_translator etc). But I am in doubt, is it good idea or not? For pros, it makes DB more clean and one simple benefit I see that DBIC schema loader detects such simple bridge-tables and creates many-to-many accessors to me. For cons I see that aggregating functions for roles will need more joinings.
What are the benefits of using separate role-bridgetable over all-in-one role-bridgetable? And what are shortcomings? I am trying to upgrade my apps using ORM (DBIx::Class), but not knowing it well yet, so considerations towards it are also really welcome.
create table book (
id_book integer primary key,
name_book text,
author_book
);
create table person (
id_person integer primary key,
name_person text
);
create table book_person (
id_person integer,
id_book integer,
role_person text,
primary key (id_person, id_book)
);
I think using role in book_person table is a good choice if one person has ONLY one role because:
There are just a few roles which you use.
To wouldn't to litter your DB when you could do it if created some more tables like book_author, book_translator.
You don't need to use as you said many joinings.
Roles in your case just an attribute and if you don't keep some extra info about roles capabilities you shouldn't create one more table for keeping binding role-person. You already keep it in book_person.
You need to create another table for role if you have:
One person has more than one role.
You keep some extra info about role as I said above.
I guess that's all.
Given that a person can have multiple roles for a book, I would create a separate table (say book_person_role) with person-id/book-id as foreign key and a role-id. Thus you get a one-to-many relation from book_person to book_person_role. I wouldn't create a table per role; that would mean changing the schema when a role is added/deleted/changed.

Converting an ER diagram to relational model

I know how to convert an entity set, relationship, etc. into the relational model but what i wonder is that what should we do when an entire diagram is given? How do we convert it? Do we create a separate table for each relationship, and for each entity set? For example, if we are given the following ER diagram:
My solution to this is like the following:
//this part includes the purchaser relationship and policies entity set
CREATE TABLE Policies (
policyid INTEGER,
cost REAL,
ssn CHAR(11) NOT NULL,
PRIMARY KEY (policyid).
FOREIGN KEY (ssn) REFERENCES Employees,
ON DELETE CASCADE)
//this part includes the dependents weak entity set and beneficiary relationship
CREATE TABLE Dependents (
pname CHAR(20),
age INTEGER,
policyid INTEGER,
PRIMARY KEY (pname, policyid).
FOREIGN KEY (policyid) REFERENCES Policies,
ON DELETE CASCADE)
//This part includes Employees entity set
CREATE TABLE Employees(
ssn Char(11),
name char (20),
lot INTEGER,
PRIMARY KEY (ssn) )
My questions are:
1)Is my conversion true?
2)What are the steps for converting a complete diagram into relational model.
Here are the steps that i follow, is it true?
-I first look whether there are any weak entities or key constraints. If there
are one of them, then i create a single table for this entity set and the related
relationship. (Dependents with beneficiary, and policies with purchaser in my case)
-I create a separate table for the entity sets, which do not have any participation
or key constraints. (Employees in my case)
-If there are relationships with no constraints, I create separate table for them.
-So, in conclusion, every relationship and entity set in the diagram are included
in a table.
If my steps are not true or there is something i am missing, please can you write the steps for conversion? Also, what do we do if there is only participation constraint for a relationship, but no key constraint? Do we again create a single table for the related entity set and relationship?
I appreciate any help, i am new to databases and trying to learn this conversion.
Thank you
Hi #bigO I think it is safe to say that your conversion is true and the steps that you have followed are correct. However from an implementation point of view, there may be room for improvement. What you have implemented is more of a logical model than a physical model
It is common practice to add a Surrogate Instance Identifier to a physical table, this is a general requirement for most persistence engines, and as pointed out by #Pieter Geerkens, aids database efficiency. The value of the instance id for example EmployeeId (INT) would be automatically generated by the database on insert. This would also help with the issue that #Pieter Geerkens has pointed out with the SSN. Add the Id as the first column of all your tables, I follow a convention of tablenameId. Make your current primary keys into secondary keys ( the natural key).
Adding the Ids then makes it necessary to implement a DependentPolicy intersection table
DependentPolicyId, (PK)
PolicyId,
DependentId
You may then need to consider as to what is natural key of the Dependent table.
I notice that you have age as an attribute, you should consider whether this the age at the time the policy is created or the actual age of the dependent, I which case you should be using date of birth.
Other ornamentations you could consider are creation and modified dates.
I also generally favor using the singular for a table ie Employee not Employees.
Welcome to the world of data modeling and design.