PostgreSQL representing different types of relations - postgresql

I have a PostgreSQL database for representing relational data. In my case the tables are as follows:
User: Basic user
Issuer: Upgraded user
Badge: Badge to issue, can only be created by issuer, and can be issued to any type of user
The relation between the tables are as follows:
Issuer - User: one to one, basic info of issuers are held in User table, issuer related info are held in Issuer table
Issuer - Badge: one to many, an issuer can create multiple unique badges
Badge - User: many to many, one user can hold multiple diff. badges and a badge can be issued to multiple diff. users
Should I combine User and Issuer tables into one and add a field to indicate the role of the user, or should I keep them separated? Note that Issuer has multiple fields that are unique to them (such as createdBadges). This way User will have both createdBadges and issuedBadges fields.
Should I create separate table for indicating the relation between Badge and User called Issuances, or should I just have array references to each other?
I want better logical coherency, better management, and higher efficiency.

issuer gets a NOT NULL foreign key to users with a unique constraint on it
badge gets a NOT NULL foreign key to issuer
a junction table user_badge has NOT NULL foreign keys to both users and badge and a primary key that is composed of both foreign keys
Don't call a table user, since that is a reserved word in SQL.

Related

Deciding primary key for DynamoDB

I have 3 fields to store in DynamoDB: identity-1, identity-2, score.
identity-1 and identity-2 are always unique in the table, i.e. no two entries can have same identity-1 or identity-2.
We want to allow entries to either have one of identity-1 or identity-2 or have both. Example:
identity-1
identity-2
score
a1
b1
s1
a2
s2
b3
s3
Access patterns are as follows:
Query identity-2 from identity-1
Query score from identity-1
Query score from identity-2
How do I define primary key in such case?
This is a "many:1" problem and there's a few ways to tackle it with DynamoDB. The simple answer here is to leverage Global Secondary Indexes (GSI). For every "identity" you wanted to do a direct look up from, you'd create a GSI.
GSI-1 would include Identity-1 as the hash key and you'd include Identity-2 and any other identities as a non-key attribute to include. You'd create a GSI for each identity you wanted to query directly on. You could also include the score as a non-key attribute if you wanted to directly look up score from any identity without having to resolve to the primary key (which we'll talk about).
The thing to consider with GSI's, though, is that they consume extra storage and throughput. If you create a GSI which includes all your attributes for every identity, you'd be paying for an additional copy of your table for each identity.
The other issue, so far, is that you haven't chosen a Primary Key for your table. You'll need a field to be your primary key and if none of your identities is non-nullable, you'll need a field which will be. It's often convenient to just call it what it is, so we'll call it pk.
You've got a few choices for pk here. Once is to define pk as a composite of your identities. For example: item.pk = item["identity-1"] || item["identity-2"]. Then you could do a query on the table for the identity == pk and if you don't find anything, you could then look up the index for the given identity. This works fine for your simple example, but as you wanted to do more complex things (such as many different identity types), you might find it to be a bit of a headache.
From past experience, my recommendation would be to adjust your approach slightly, however, and have an "users" table and a "scores" table. "users" would have a pk of a guid unique for every user and all their identities (call it "user_id"), you could then create a GSI for that table for every identity back to user_id. Then scores would then use "user_id" as the pk as well with no need for an index. Your application would always resolve to a "user_id" when a user was logged in or otherwise identified - then you can search for score without needing to track identity and you can look up all the associated identities or other user information without needing to create a very "fat" index of every identity->every other identity.

Unique Key / Idempotency key migration

I am using PostgreSQL and I need to migrate Idempotency/unique key from customer id to user id.
Customer id is one to many mapped to user id.
Currently the unique index is customer id + date string
Further going, I expect no more than one entry in DB per user per day, therefore the unique index will be user id + date string.
How do I handle such migration without downtime?

How to add non unique value into a unique list while still allowing value to be updatable

I have a simple database schema with User records
User
id - uuid pk
email - not null
List
id - uuid pk
List Entry
id - uuid pk
userId - uuid references User (id)
listId - uuid references ListEntry (id)
The trick is the system needs to guarantee uniqueness of User emails within a list while still allowing for the email of the User record to be updatable.
An obvious solution is the add email to the List Entry table with a unique index, but, this runs into issues with the requirement that the email is updatable. Especially because the application treats a User as its own standalone entity that can be modified in a place that does not know about Lists and ListEntries.
I do control the code executing updates and I have considered attempting a solution using serializable transactions to prevent duplicates, but, that seems worse than trying to keep the two email fields in sync.

What's the relationship between res.partner and res.user?

I am new to odoo v8 and i am not able to understand the relationship between res_partner and res_users tables and also with hr_employee table are they all related?
The relationship between res.partner and res.user is that res.user inherits from res.partner using an inheritance type called "Delegation Inheritance" (see documentation).
Because of "Delegation Inheritance" every res.user record has a mandatory internal connection to a corresponding res.partner record using a field partner_id. What is this connection all about is to directly use all the fields of res.partner to store data shared by res.user and res.partner (i.e. name, phone, etc... if for example you refer to phone property of a record of res.user you'll get the value stored in the corresponding res.partner record) so res.user has to define fewer number of fields on it's own, like password, login, etc..
Note also that because of this relation res.user can NOT exist in the system without corresponding res.partner, it's why every res.user has one, but nonetheless res.partner can exist without res.user.
hr.employee have m21 with res.users (user_id)
res.users have m21 with res.partner(partner_id)
Actually only res.users has a "real" relationship to res.partner, because with every user odoo will create a partner (per default no customer and no supplier). this partner will be used e.g. for emails and the followers system in odoo.
But you can have partners without users, too. That will be a normal partner, for defining customers and suppliers.
And finally there is the employee. You can set a user on it. If i recall right, the user will be used for attendances and timesheets.

How can Code First be used to map surrogate keys

I have legacy tables with Primary keys. These tables also have surrogate keys that have been used to relate one table to another. I would like to map the Membership.User table (uses a Guid PK) but has a property UserName which holds the surrogate key which relates it to the DepoMembers table. DepoMembers has a numeric PK - but has a surrogate key UserName. UserNames are guaranteed to be unique.
In Linq2SQL - to relate these tables in the designer - we add an association where User.UserName is linked to DepoMembers.UserName - and set the multiplicity of the Association to 1:1. then Modify the Navigation Names to singular.
If we take DepoMembers as the Principal End of the relationship - it should follow that If Membership.User does not exist (As in the case - where a user does not manage the application site but exist in DepoMembers) the Navigation Property User will be Null.
How can this be done in Code First ...
The only alternative I've come up with so far is to create a property DepoMembers.User which uses the UserName Property to retrieve the User using the datacontext.
Ren