how to avoid duplicates for unique Id's with timestamp - sql

Hi I have a situation like i am inserting a unique value into Data Base along with primary key
by generating in java code. This unique Id has time stamp Ex:'BatchID16Jul1411111111'. where it is extended up to milliseconds.Now if two users hit at same time same unique ids are generated.
Is there any way to make this times tamp unique even it is called at same time.
Is it possible by getting auto increment number from DB.
Can any one suggest me solution for this situation.
Thanks in advance
Mahesh

Yes, it is possible to get an auto-incremented number from the database. The exact syntax depends on the database. These typically use one of three methods:
An auto-increment declaration in the create table statement;
An identity declaration in the create table statement; or,
A sequence assigned as a default value to the primary key column.
Note, though, that the auto-incremented number will not have any meaning. So, you will need a separate column for the 'BatchId' and for the date time.

Related

Are PostgreSQL autoicrementing id scalable?

I am new to SQL, I am coming from NoSQL.
I have seen that you need to make a unique id for you rows if you want to use unique ids. They are not automatically made by the database as it was in MongoDB. One way to do so is to create auto-incrementing ids.
Are PostgreSQL auto-incrementing id scalable? Does the DB have to insert a row at a time? How does it work?
-----EDIT-----
What I am actually wondering is in a distributed environment is there a risk that two rows may have the same id?
In Postgres, autoincrement is atomic and scalable. In case some inserts fail, some ids can be missing from sequence but inserted are guaranteed to be unique.
Also, all primary keys don't have to be generated. See my answer to your first question.
Autoincrementing columns that are defined as
id bigint PRIMARY KEY DEFAULT nextval('tab_id_seq')
or, more standard compliant, as
id bigint PRIMARY KEY GENERATED ALWAYS AS IDENTITY
use a sequence to generate unique values.
A sequence is a special database object that can very efficiently supply unique integers to concurrent database sessions. I doubt that any identity generator, be it in MongoDB or elsewhere, can be more efficient.
Since getting a new sequence values accesses shared state, you can optimize sequences for high concurrency by defining them with a CACHE value higher than 1. Then each database session that uses the sequence keeps a cache of unique values and doesn't have to access the shared state each time it needs a value.

Creating my Custom Unique Key

I have a table in my SQL Server. Currently I am using the identity column to uniquely identify each record but my changing needs required a unique key generated in a certain format (as specified by my client). I have tried to generate the unique key from my application by appending a unique integer (that is incremented on every insert) to the format specified my client is not satisfied with my current solution.
It would be great if I can be directed to a better technique to solve my problem rather then my current solution.
The format is like:
PRN-YEAR-MyAppGeneratedInt
Basically, keep the current identity column. That is the best way for you to identify and manage rows in the table.
If the client needs another unique key, then add it. Presumably, it will be a string (given that it has a "format"). You can possibly create the key as a generated column. Alternatively, you may need to use a trigger to calculate it.
In general, integers are better for identity columns, even if end users never see them. Here are some advantages:
They encode the ordering of row insertion in the database. You can, for instance, get the last inserted row.
They are more efficient for foreign key references (because numbers are fixed-length and generally shorter than strings).
They make it possible to directly address a row, when data needs to be fixed.
You can create a SEQUENCE to serve your purpose which were introduced in SQL Server 2012. A real detailed explanation about SEQUENCE can be found here.
Hope this helps :)
As per you specified in the comments the format let me also give you an example that how you can solve your problem using a sequence:
First create a sequence like:
CREATE SEQUENCE SeqName
AS int
START WITH 1
INCREMENT BY 1
CYCLE
CACHE
Next you can use this sequence to generate your desired unique key in you app program.
Get the next value for sequence "SELECT NEXT VALUE FOR SeqName;"
Create a string using the value like :String key= "PRN"+year+SeqValue;
Finally store this string as your unique key in your Insert statement.
You can write the application code as per you need :)
You could create a Computed Column and just append the identity
('Custom_'+CONVERT(varchar(10),iden))

Confusing t-sql exam answer about sequence or uniqueidentifier

I found a t-sql question and its answer. It is too confusing. I could use a little help.
The question is:
You develop a database application. You create four tables. Each table stores different categories of products. You create a Primary Key field on each table.
You need to ensure that the following requirements are met:
The fields must use the minimum amount of space.
The fields must be an incrementing series of values.
The values must be unique among the four tables.
What should you do?
A. Create a ROWVERSION column.
B. Create a SEQUENCE object that uses the INTEGER data type.
C. Use the INTEGER data type along with IDENTITY
D. Use the UNIQUEIDENTIFIER data type along with NEWSEQUENTIALID()
E. Create a TIMESTAMP column.
The said answer is D. But, I think the more suitable answer is B. Because sequence will use less space than GUID and it satisfies all the requirements.
D is a wrong answer, because NEWSEQUENTIALID doesn't guarantee "an incrementing series of values" (second requirement).
NEWSEQUENTIALID()
Creates a GUID that is greater than any GUID
previously generated by this function on a specified computer since
Windows was started. After restarting Windows, the GUID can start
again from a lower range, but is still globally unique.
I'd say that B (sequence) is the correct answer. At least, you can use a sequence to fulfil all three requirements, if you don't restart/recycle it manually. I think it is the easiest way to meet all three requirements.
Between the choices provided D B is the correct answer, since it meets all requirements:
ROWVERSION is a bad choice for a primary key, as stated in MSDN:
Every time that a row with a rowversion column is modified or inserted, the incremented database rowversion value is inserted in the rowversion column. This property makes a rowversion column a poor candidate for keys, especially primary keys. Any update made to the row changes the rowversion value and, therefore, changes the key value. If the column is in a primary key, the old key value is no longer valid, and foreign keys referencing the old value are no longer valid.
TIMESTAMP is deprecated, as stated in that same page:
The timestamp syntax is deprecated. This feature will be removed in a future version of Microsoft SQL Server. Avoid using this feature in new development work, and plan to modify applications that currently use this feature.
An IDENTITY column does not guarantee uniqueness, unless all it's values are only ever generated automatically (you can use SET IDENTITY_INSERT to insert values manually), nor does it guarantee uniqueness between tables for any value.
A GUID is practically guaranteed to be unique per system, so if a guid is the primary key for all 4 tables it ensures uniqueness for all tables. the one requirement it doesn't fulfill is storage size - It's storage size is quadruple that of int (16 bytes instead of 4).
A SEQUENCE, when is not declared as recycle, guarantee uniqueness, and has the lowest storage size.
The sequence of numeric values is generated in an ascending or descending order at a defined interval and can be configured to restart (cycle) when exhausted.
However,
I would actually probably choose a different option all together - create a base table with a single identity column and link it with a 1:1 relationship with all other categories. then use an instead of insert trigger for all categories tables that will first insert a record to the base table and then use scope_identity() to get the value and insert it as the primary key for the category table.
This will enforce uniqueness as well as make it possible to use a single foreign key reference between the categories and products.
The issue has been discussed extensively in the past, in general:
http://blog.codinghorror.com/primary-keys-ids-versus-guids/
The constraint #3 is why a SEQUENCE could run into issues as there is a higher risk of collision/lowered number of possible rows in each table.

Rails & Postgresql create a field that auto increments from 1

I'm looking to create a field called id_visual in my table orders which starts at 1 and auto increments from there. I could create a method in my model to do it but I thought there must be a better more foolproof way. Any ideas?
From what I can tell, you want a secondary id based on the primary id? The identity key can only be table based and can not be dependent on another key. You will have to do this in code and then save it to a new field on before_create. The easiest way to do this is for each order that you want to id, get the count of all orders less than or equal to the one you are working with based on whatever the primary key is. Its a simple one query calculation.
This is something your database should be providing at some level, either in a transaction or with some other locking.
Take a look at this question for some ways to get postgres configured to auto-increment a column:
PostgreSQL Autoincrement

Should i have a primary ID? i am indexing another field

Using sqlite i need a table to hold a blob to store a md5 hash and a 4byte int. I plan to index the int but this value will not be unique.
Do i need a primary key for this table? and is there an issue with indexing a non unique value? (I assume there is not issue or reason for any).
Personally, I like to have a unique primary id on all tables. It makes finding unique records for updating/deleting easier.
How are you going to reference on a SELECT * FROM Table WHERE or an UPDATE ... WHERE? Are you sure you want each one?
You already have one.
SQLite automatically creates an integer ROWID column for every row of every table. This can function as a primary key if you don't declare your own.
In general it's a good idea to declare your own primary key column. In the particular instance you mentioned, ROWID will probably be fine for you.
My advice is to go with primary key if you want to have referential integrity. However there is no issue with indexing a non unique value. The only thing is that your performance will downgrade a little.
What are the consequences of letting two identical rows somehow get into this table?
One consequence is, of course, wasted space. But I'm talking about something more fundamental, here. There are times when duplicate rows in data give you wrong results. For example, if you grouped by the int column (field), and listed the count of rows in each group, a duplicate row (record) might throw you off, depending on what you are really looking for.
Relational databases work better if they are based on relations. Relations are always in first normal form. The primary reason for declaring a primary key is to prevent the table from getting out of first normal form, and thus not representing a relation.