How to prevent duplicate entries in database - database

I am trying to implement a friend request feature and using oracle 11 xe database.
My user1 sends a request to user2 so a record in database is created as
requestId: 12,
fromUser: user1,
toUser: user2,
status : 0 (indicating pending),
creationTime: timestamp
I want to prevent the same entry i.e user1 can send friend request only once not twice. request Id is primary key and user1 and user2 are both foreign keys.
what kind of oracle database constraint or sql command i should add to my table .
Please help

If you want to have a unique combination of requestId, fromUser and toUser and such that none of the columns could never be NULL. Then make the combination as Primary Key.
Alternatively, if you want to allow NULL values for and only want fromUser and toUser to always be UNIQUE, then create a unique index on them and create a unique constraint. The unique constraint will use the unique index.
For example,
CREATE UNIQUE INDEX indx_usr_uk
ON table_name (fromUser, toUser);
ALTER TABLE table_name
ADD CONSTRAINT user_unique UNIQUE (fromUser, toUser);
If you don't explicitly create an unique index, then Oracle will use any existing index.

You might have combination of 'fromUser','toUser' columns as primary key. As one user can send the friend request to another user, only once.

Related

Would data be in the same partition if I use composite keys ?

Considere the following case regarding Cassandra database: I must perform a batch statement with some related data, e.g: table users and table users_by_username. I want to insert on user creation data on both tables. It's a transaction. In Cassandra documentation says the batch statement cannot reach multiple partitions. If I model the primary key as a composite key like following :
CREATE TABLE IF NOT EXISTS user(
id text,
tpe text,
username text,
PRIMARY KEY((tpe, id))
);
CREATE TABLE IF NOT EXISTS user_by_username(
username text,
tpe text,
id text,
PRIMARY KEY((tpe, username))
);
Example of rows:
user: ('1', 'users', 'lucasrpb')
user_by_username: ('lucasrpb', 'users', '1')
My doubt: will data be on the same partition to be able to do the batch?
Partitions are within a table, not across tables. However, the token for data, which is used to identify which replicas will host the data, is based on the partition key (the first column in the primary key, or the first column(s) surrounded in parenthesis).
In your case, the partition key for 'user' is (tpe, id) and user_by_username is (tpe, username). Because of this, the token for the data will likely not be the same.
If the primary key for user was (tpe, id), user_by_username (tpe, username), the partition key for each case would be tpe, therefore granted tpe was the same, the token would be the same and therefore the data would be stored on the same replicas.
In any case, I would not recommend batching operations to update user_by_username and user together, but it'd be better in the case where the partition key was the same as less C* nodes need to be written to in the batch.
Since the only difference between your tables is your primary key, I think a good candidate for you if you are on a 3.0+ version would be to look into materialized views which were introduced in 3.0. With this you could set up a user_by_username view off of the user table like:
CREATE MATERIALIZED VIEW user_by_username AS
SELECT * FROM users
WHERE username IS NOT NULL
PRIMARY KEY ((tpe, username));
This way you only have to make changes to user, which will then be propagated to user_by_username for you.

Prevent non-primary key column to have duplicates

I read in this site that it is recommended use an auto-number ID rather than username for primary keys because it will not change. However, how do I prevent the database to have only unique usernames. I am using Access.
In Access, open the table in Design View and click on the username field. In the "Field Properties" pane at the bottom, select Yes (No Duplicates) for the Indexed property. That will prevent duplicate username values from being entered.
Set unique constraint on username column (some main table for user).
You always can validate before inserting (for prompting user) or on trigger before insert.
I take it you've already made the table, so run this query:
ALTER TABLE users
ADD UNIQUE(username)
Change table name and column name in the query to match your table and column name, obviously.
Here's the reference: http://www.w3schools.com/sql/sql_unique.asp

EF5 How to Add missing Relationships

Hi i have a database first EF5 model defined.
My user table has a primary key guid UserGUID
and another key field UserID with an auto-incrementing integer.
I have created a table called UserCustomField which has
UserID and I have created a foreign key constraint to UserID in my User Table.
When I update the model from the database all foreign key relationships to primary keys are generated but none to Key fields. Ignoring the potential point about using the guid through all my tables.....
A/ shouldn't EF add this relationship?
B/ how can i manually add it?
Cheers
Tim
A: No.
B: You cannot.
EF is able to use relations only when they point to primary key so either change User table to use UserID as primary key and remove UserGuid or change UserCustomField table to point UserID to UserGuid in the User table.
The reason why it doesn't work is that your database requires UserID in User table to be marked as unique (that means unique constraint) and EF doesn't support unique constraints yet.

A better database design on SQL Server?

In SQL Server, I need to design a User table. It should have a UserID (int), a RoleID (int) and a UserName (nvarchar(255)).
A user can be assigned with a name but possibly multiple roles so a UserId may correspond to multiple RoleIDs. This makes it difficult to assign primary key to UserID as UserID may duplicate.
Is there any better design other than breaking it up into multiple tables?
You should have:
1. a user table with UsertId(int), UserName (Varchar)
2. a role table with RoleId(int), RoleName(Varchar)
3. a user_role table with user_id(int), role_id(int)
And don't forget to add the proper indexing and foreign keys.
Ye, have a table Roles, then RolesUsers with UserID and RoleID, and lastly a Users table
edit: where the UserID + RoleID in the RolesUsers are a composite key

Constraint column with specific value in table scope

Based on Constraint for only one record marked as default would the same approach of a view and unique clustered index apply if I wanted to achieve the same result at a table scope?
I have a table called Accounts. There can be only one System account, however there can be many Partner and Client accounts. Each type of account does not vary in terms of the columns but instead with just the Type column.
ID | Type | Name
1 System Contoso
2 Partner Wingtip
3 Partner Northwind
4 Client Adventure Works
5 Client Fabrikam
In the above I want to prevent adding another System account, but allow many partner and client accounts. It feels like a concern that belongs in the database as opposed to the domain (maybe I'm wrong)?
If you know that the system account will always have ID number 1, you can implement this with a CHECK constraint. Something along these lines . . .
create table accounts (
id integer primary key,
type varchar(15) not null,
name varchar(15) not null,
unique (type, name),
check (
(id = 1 and type = 'System') or
(id <> 1 and type <> 'System')
)
);
In fact, if this is your database, the system account can have any id number. Just change the CHECK() constraint to match.
If you're building for deployment to a client site, you can add the system account before deployment. (And you probably should, regardless of how you handle the constraints.)
Think about about what to do when a user tries to delete rows from this table. (Especially that system account row.) Then think about what to do when a database admin tries to delete rows from that table.
You can probably use a foreign key constraint (no cascade) or a trigger to prevent a database admin from accidentally deleting the system account. The admin can probably get around those restrictions, but you'd hope she knows what she's doing if she's willing to go that far to delete a row.

Resources