Generate incremental unique IDs for users on registration - asp.net

I have a website wherein I need to users to register themselves by adding their details and submitting. On submitting each user should be allocated incremental unique ids. To test this I had 15 users enter necessary details on the site and then click on register simultaneously, however two set of users got the same ids allocated to them. This is not a problem when all register at different times, then the allocation of ids is unique.
How do I ensure each user gets unique ids even when they register simultaneously.

The "easiest" way to give each user a unique ID would be to either use an IDENTITY column on your user table (if you want the ID to be allocated when the record is successfully written to it), or a SEQUENCE object if you want to get a unique ID before creating the user account in the database.
create table MyUserTable (
UserID int identity(1,1) NOT NULL constraint PK_MyUserTable PRIMARY KEY CLUSTERED
,UserName nvarchar(50)
,Email nvarchar(100);
insert into MyUserTable output inserted.UserId values ('MyUserName', 'me#example.com');
Will write the record to the table and return the ID that was created.
If you want to fetch an ID before writing to the table:
CREATE SEQUENCE UserIds as int start with 1 increment by 1;
create table MyUserTable (
UserID int NOT NULL constraint PK_MyUserTable PRIMARY KEY CLUSTERED
,UserName nvarchar(50)
,Email nvarchar(100);
select next value for UserIds
-- Do whatever you need to do in the application
insert into MyUserTable (UserId,UserName,Email) values (UserIdYouGotEarlier, 'MyUserName','me#example.com');
Understand that with both approaches, you are not guaranteed to have sequential IDs. In the case of a transaction rollback, these will both still auto-increment and those values will be "lost." But you shouldn't be depending upon them being sequential in the first place.
You'll probably want a unique constraint on those username fields too.

Related

How to insert row into 2 tables with a one-to-one relationship in SQL Server

Suppose I have 2 tables with a one-to-one relation:
tblOrder (orderId, orderName, totalPrice, billId)
tblBill (billId, billAmount, cardNumber)
The orderId in tblOrder and billId in tblBill are the primary key and they are both identity keys. Also billId in the tblOrder is the unique foreign key.
In the front end using Asp.net, I want the customers to enter the tblOrder information first into the database, then I want them to enter tblBill information. But I want to automate the process of setting the billId foreign key on the tblOrder. Problem is when multiple users will use the system at same time how can I know which bill will belong to which order?
One solution I thought of was to insert an empty row in tblBill and set that id column value to the tblOrder's billId foreign key. And update the bill information when customer enters the bill information in front end. But it doesn't seem like an optimal solution since one empty row insertion will happen for every purchase.

getting the right data model with dynamodb

I am about to create my first dynamodb table and can't find a proper solution to model my requirements. It sounds very basic, but probably my brain is still too much into relational database world.
I want to do store something similar like that:
A user can buy a product (once or several times). What I want to store is username, product_id
The only things I need to query later are:
which products have been purchased by user X
how many times were they purchased
First I considered having having an item with two attributes: username and product_id. But then I cannot use username as primary key (a user can buy more than once) neither can I user username + product_id (user can buy a product several times)
Now I would go for having username, product_id, counter and taking username + product_id as primary key. However, I will always need to check first if a product was already purchased and update it, otherwise create a new entry. For getting all products of a user I would create a global secondary index on username.
However, I am not very sure if this is the right way. Any feedback would be great!
There are probably a number of ways to do this and I don't know all of your requirements so I can't guarantee this is the right answer for you but based on your description, this is what I would do.
First, I'm assuming that each order has some sort of unique order number associated with it. I would use this order number as the primary key of the table. I wouldn't use a range key. This would ensure that the constraint that all primary keys be unique is met. In addition, when I write the data to DynamoDB I would also write the username and the product_id as additional attributes.
Next, I would create a Global Secondary Index that uses the username as the primary key and the product_id as the range key. Unlike the primary key of the table, GSI keys do not have to be unique so if a user purchased a particular product more than once, this would be fine. This GSI would allow me to perform queries such as "find all orders by username" or "find all orders where username purchased product_id".
If you also needed to do queries like "find all usernames who purchased product_id" you would need another GSI that used product_id as the primary key and username as the range key.

Duplicate record no entered in database table

I am developing a .ASPX page with following design
Firstname
Lastname
Address
City
Mobile
This is represented to user with labels and textboxes.
When user clicks on Save button, data is saved in SQL Server 2008 Express database table.
Table has following schema
RecordNo-int(PK)
Firstname-nvarchar(50)
Lastname-nvarchar(50)
Address-nvarchar(500)
City-nvarchar(50)
Mobile-nvarchar(12)
At the time of page loading, I also display recordno to user.
This record number is generated based on how many records are there in the table.
I get the number of records and just increment it by 1 and put it against RecordNo.
Now, if this is happening on one PC, it works fine.
First entry will be represented with RecordNo 1
and so on.
But if, there is no record in the table, and the same page is opened by 4 different users at the same time, then all will
be represented with RecordNo 1.
and then, user who first click save button, will be able to save the data perfectly.
But other three users will encounter error, because they are entering information with RecordNo 1, which is already entered.
How do i overcome this?
Each new entry should be given new and unique RecordNo.
Is there any way i can do this?
Why to take headache of showing the number of entries you just set the primary key column to Identity(1,1) which will increment that column value by 1 every time a new row is inserted. This is how 'n' number of user will be able to make entries concurrently.
Set an Identity Cloumn as :
RecordNo int Identity(1,1) Primary Key
In Identity(1,1) first 1 is Starting Value and Other is Increment Value.
Use the code below if you don't want to use Identity:
SELECT * FROM (SELECT ROW_NUMBER() OVER (ORDER BY RecordNo ASC) AS RecordNumber,
FirstName,LastName,Address,City,Mobile from yourTableName) AS RecordNo
Make RecordNo an IDENTITY(1,1) field and forget about all your logic to generate the key. IDENTITY does this for you automatically.
If you require you can call SCOPE_IDENTITY() after the record is inserted to capture the generated value.

SQLite: Ordering my select results

I have a table with unique usernames and a bunch of string data I am keeping track of. Each user will have 1000 rows and when I select them I want to return them in the order they were added. Is the following code a necessary and correct way of doing this:
CREATE TABLE foo (
username TEXT PRIMARY KEY,
col1 TEXT,
col2 TEXT,
...
order_id INTEGER NOT NULL
);
CREATE INDEX foo_order_index ON foo(order_id);
SELECT * FROM foo where username = 'bar' ORDER BY order_id;
Add a DateAdded field and default it to the date/time the row was added and sort on that.
If you absolutely must use the order_ID, which I don't suggest. Then at least make it an identity column. The reason I advise against this is because you are relying on side affects to do your sorting and it will make your code harder to read.
If each user will have 1000 rows, then username should not be the primary key. One option is to use the int identity column which all tables have (which optimizes I/O reads since it's typically stored in that order).
Read under "RowIds and the Integer Primary Key" # http://www.sqlite.org/lang_createtable.html
The data for each table in SQLite is stored as a B-Tree structure
containing an entry for each table row, using the rowid value as the
key. This means that retrieving or sorting records by rowid is fast.
Because it's stored in that order in the B-tree structure, it should be fast to order by the int primary key. Make sure it's an alias for rowid though - more in that article.
Also, if you're going to be doing queries where username = 'bob', you should consider an index on the username column - especially there's going to be many users which makes the index effective because of high selectivity. In contrast, adding an index on a column with values like 1 and 0 only leads to low selectivity and renders the index very ineffective. So, if you have 3 users :) it's not worth it.
You can remove the order_id column & index entirely (unless you need them for something other than this sorting).
SQLite tables always have a integer primary key - in this case, your username column has silently been made a unique key, so the table only has the one integer primary key. The key column is called rowid. For your sorting purpose, you'll want to explicitly make it AUTOINCREMENT so that every row always has a higher rowid than older rows.
You probably want to read http://www.sqlite.org/autoinc.html
CREATE TABLE foo (
rowid INTEGER PRIMARY KEY AUTOINCREMENT,
username TEXT UNIQUE KEY,
...
Then your select becomes
select * from foo order by rowed;
One advantage of this approach is that you're re-using the index SQLite will already be placing on your table. A date or order_id column is going to mean an extra index, which is just overhead here.

SQLite update on select (or vice versa)

Is there a one-statement select-and-update (or update-and-select) method in SQLite?
A trigger can invoke select, but that doesn't allow update to be used in an expression:
CREATE TABLE id ( a integer );
CREATE TRIGGER idTrig AFTER UPDATE ON id BEGIN SELECT old.a FROM id; END;
INSERT INTO id VALUES ( 100 );
INSERT INTO test VALUES ( (UPDATE id SET a=a+1) ); -- syntax error
(Is a triggered select only accessible via the C API?)
I generate object IDs for several databases from a single ID database (with a single row for the next available ID). I'd like to select-and-update on the ID db in one statement, so that concurrent db connections which attach the ID db won't have trouble with this (where two connections could insert before either updates):
INSERT INTO tab VALUES ( (SELECT uuid||oid AS oid FROM id.tab), ... );
UPDATE id.tab SET oid = oid+1;
I'll start with the prerequisite nag: why not use GUIDs? They don't require central authority and are thus more efficient and easier to work with.
If you really need a central ID store, you can make the ID an autoincrement and fetch it with SELECT last_insert_rowid(). If you have to generate your own IDs, then make the ID column a primary key, so you can generate the ID, INSERT it, and retry if the INSERT fails.
This discussion presents two possible solutions:
http://www.mail-archive.com/sqlite-users#sqlite.org/msg10705.html

Resources