Can SYS_GUID() function generate same guid at another db - oracle

I am planning to use SYS_GUID() function to generate primary key in an existing table(Primary key does not exist in that table as of now)
I wanted to know if in certain case if we sync data from one database to another , is it possible that Oracle generate same guid at another db ?
Thank you

No. GUID is Globally unique. See alsi the documentation https://docs.oracle.com/cd/B13789_01/server.101/b10759/functions153.htm

To be correct, a collision might be possible but is very unlikely as SYS_GUID() involves stuff like host identifier and so on. If you are talking about the same database but different user/schemas you are perfectly safe as the unique number is unique across all users.

Related

How to use ActiveRecord (without Rails) with database that doesn't have primary keys

I now writing automation program for system based on MSSQL Server, using Ruby 1.9.3 and ActiveRecord 3.1.6 without Rails.
Tables have nonstandard ids (stk_id, urb_id, instead of id), also some tables haven't primary keys.
Before I added column id and set it as primary key my program worked very slowly. I waited nearly 3 minutes while the program makes two operations of selection and some little processing in table with 9000 records. But when I added column id and set it as primary key, these operations were finished in less then 10 secs.
Yet another problem I found in deletion operation: it doesn't work at all without primary key in table. Error when trying to delete without primary key:
undefined method `to_sym' for nil:NilClass
I can't modify the table structure of the production database. Maybe someone knows how to solve this problem without adding id columns and setting primary keys?
Remark: A database without primary keys is BAD !
http://www.helium.com/items/1539899-why-a-relational-database-needs-a-primary-key
Using nonstandard keys is no problem, just use self.primary_key = "stk_id"
You may also use composite_primary_keys:
https://github.com/drnic/composite_primary_keys
Create indexed views on each of the tables with no primary key. A unique clustered index as well as other indexes as needed can be applied. Including a single table in the view should prevent you from violating the many conditions an indexed view requires/prohibits.
I suggest looking into using Sequel instead of ActiveRecord. It is not opinionated about the database schema like ActiveRecord is and may be easier to use with a database schema you can't modify.

SQL Azure and Membership Provider Tenant ID

What might be a good way to introduce BIGINT into the ASP.NET Membership functionality to reference users uniquely and to use that BIGINT field as a tenant_id? It would be perfect to keep the existing functionality generating UserIds in the form of GUIDs and not to implement a membership provider from ground zero. Since application will be running on multiple servers, the BIGINT tenant_id must be unique and it should not depend on some central authority generating these IDs. It will be easy to use these tenant_id with a SPLIT AT command down the road which will allow bucketing users into new federated members. Any thoughts on this?
Thanks
You can use bigint. But you may have to modify all stored procedures that rely on user ID. Making ID global unique is usually not a problem. As long as the ID is the primary key, database will force it to be unique. Otherwise you will get errors when inserting new data (in that case, you can modify ID and retry).
So the most important difference is you may need to modify stored procedures. You have a choice here. If you use GUID, you don't need to do anything. But it may be difficult to predict how to split the federation to balance queries. As pointed out in another thread (http://stackoverflow.com/questions/10885768/sql-azure-split-on-uniqueidentifier-guid/10890552#comment14211028_10890552), you can sort existing data at the mid point. But you don't know future data will be inserted in which federation. There's a potential risk that federations will become unbalanced, and you may need to merge and split them at a regular interval to keep them in shape.
By using bigint, you have better control over the key. For example, you have two federations. The first has ID from 1 to 10000, and the second has ID from 10001 to 20000. When creating a new user, you first check how many records are in each federation. Suppose federation 1 has 500 records and federation 2 has 1000 records, to balance the load, you choose to insert to federation 1, so you choose an ID between 1 and 10000. But using bigint, you may need to do more work to modify stored procedures.

Surrogate key in 'User' / 'Role' tables for desktop app? Whats the purpose?

I have to add some security for a C#/.NET WinForms/Desktop application. I am using Oracle DB back-end.
The tables are simple: User (ID,Name), Role(ID,Role), UserRole(UserID,RoleID).
I am using the windows account name to populate User table. Role table will for now just be simply 'Admin','SuperUser','BasicUser'...
Since no two people could ever possible have the same windows account name... even when I do not control these name management (netops does, hence why I want to use windows accounts so I don't have to manage it ;)). For Role table, I should again never have dupe value - I control the input, there will only be 3 (tactical app going away within year). UserRole is a join table to represent the Many-To-Many relationships of users and roles, so no surragate key is justified.
Simple question - Why bother with 'ID' (int) in the User and Role table? Any point or advantage here? Is this one of those 'I've always done it this way' type things? Or have I just not done this in awhile and forget the reason?
Names change - primary key values must not. Abigail Smith becomes Abigail Jones and the username changes but a surrogate key protects against having to cascade those changes everywhere.
If you are using a surrogate key but there is a column or combination of columns which should be unique, then enforce that using a unique index. There's a good chance you'll want indexes on your user.name and role.role columns anyway, and a unique index is more space efficient and supplies useful metadata to the optimizer. If you have a surrogate key but don't have another combination of columns that uniquely identify a row then think again whether you have your entity definition right.
One caution. Especially for very narrow tables with few access paths, you may use an index-organized table. Oracle will only allow an index organized table on the primary key, but does allow foreign keys against a unique set of columns (if it is enforced by a unique constraint, not simply a unique index).
It is possible that you'll end up with a table where a unique ID is enforced through a unique index and treated as PK by an ORM and used as the parent for foreign key relationships, but the primary key (as defined in the DB) is the rolename/username/whatever because you want that as the driver for an index-organised table.
A surrogate key is not required on intersection tables, but here are a few reasons to do so:
Consistency: If every table has a single artificial key, you always know the key name when you know the table name.
Ease Of Use: Less typing — one key means ON and WHERE clauses are shorter and thus less error-prone.
Interoperability: Some ORMs only work well with tables with a single primary key column.

How to I merge two databases with same schema that are on Heroku?

I created two applications that were essentially identical on heroku. They started off different because I was testing uploading to heroku and having some challenges making the adjustments.
But now things seem to be working, but both have data that I would like to consolidate. Since they run off the same git repository, the code is the same, as are the migrations.
Seems like I need to bring it down locally and merge, but not exactly clear how to do that. Did some searches on Google and nothing clear.
I'd like some help in terms of a step-by-step, I don't have a clear process.
1) I have two apps on heroku where I have the databases. They have the same schemas;
2) I don't need to know where the data came from: I just need it all to reside in a single database
3) I would like to be able to do it with specific sql commands, versus manually opening (not sure how I would do that) and then munging since there are about 10 different interrelated tables.
Thanks!
There is not automatic way to do this since there is no way to automate this in a generic fashion (without doing some stuff you would want to do). Therefore, it'll take a few steps, but you can leverage tools all along the way.
You can use Heroku's built-in tools to get a dump of the table. First download and import the data into your database, and then dump it out into a text file (SQL format).
Once you have one of the data sets in SQL as text, you need to edit the file a little. You need to make it an import script instead of a "rebuild the database" script that starts by deleting existing rows (or tables). If you're careful, it may already be in the right format, but likely something will be off.
There are a few gotchas you can run into:
If you have generated keys for records-- which you probably do-- then you'll have to renumber them in the data set you are importing. There may be a way to export them without generated keys, but what I have done is use a quick grep to renumber them outside of the range of the database I'm merging into.
If there are references to theses keys in other tables (as foreign keys), you'll have to renumber there as well.
Some tables may be "reference tables", and the same on both systems, so you can skip importing them.
Some tables may not need to be merged.
Once you have the text file in good shape, run it locally and test it. If it messes things up, don't worry-- just download the production data (the one you're importing into), and try again. Iterate until you have everything working well locally. Then, upload the file to heroku.
I know it sounds like a few steps-- and it is. There are no tricky problems to solve, though. You just need to go slowly and carefully. Get someone to pair with you on it to help you think it through.
Assuming you don't need to eliminate duplicates, you can do this for each table
insert into db1.tablea
select * from db2.tablea ;
Some complications:
if the tables have id columns, you need to make sure they don't clash, by replacing old ids with new ids
but, since the ids are the keys that link the tables, you need to make sure that new ids match in each table.
Here's a quick and dirty way to do it:
Find the highest id in any table in the first database.
Call this max_key_db1.
Then update all keys in the second database to be current_value plus max_key_db1.
Note that you'll need to update both primary keys and foreign keys for this to work, e.g.:
update db2.tablea set id = id + max_key_db1, foreign_id = foreign_id + max_key_db1;
update db2.tableb set id = id + max_key_db1, a_id = a_id + max_key_db1;
etc.
Now you have a self-consistent db2 with all keys (primary and foreign) with values that don't exist in db1; in other words, you keys are unique across both databases.
Now you can insert the rows from db2 into db1:
insert into db1.tablea
select * from db2.tablea ;
Note this won't work if the tables inserted into create their own ids using auto-increment or triggers; in this case you'll have to specify the ciolumns explicitly and turn off any auto-generated ids:
insert into db1.tablea( id, foreign_id, col1, ...)
select id, foreign_id, col1 from db2.tablea ;
Alternately, you can leave db2 unaltered, by doing this all in one step for each table:
insert into db1.tablea( id, foreign_id, col3, col4)
select id + max_key_db1, foreign_id + max_key_db1, col3, col4 from db2.tablea ;
Of course, do this all inside a transaction, and don't commit until you're sure you've gotten every table and all are correct. And do this on copies of your databases.
Now, since you used the highest key in db1 regardless of table, likely your ids won't be consecutive, but who cares? Keys are keys. What you will need to do is reset any auto_increment or sequence, for each table, so that teh next auto-generated key is higher than the highest key in that table. How you do that depends on what RDBMS you're using.
Going to close this -- decided to just manually select the right data and re-enter it so I can do some error checking -- a pain but this approach doesn't seem to have an easy answer. Note to self: keep all production data in production versus test-driving.
If you only need to do this once, you could get it done easily using ms access.
You can work out any conflict by creating some query in the visual query designer.
You can connect to an sqlite3 database by using the odbc driver for sqllite3 and link those tables in access.

Random ID generation on Sign Up - Database Performance

I am making a site that each account will have an ID.
But, I didn't want to make it incrementable, meaning:
id=1
id=2
...
id=1000
What I want is to have random IDs:
id=2355
id=5647734
id=23532
...
(The reason is to avoid robots to check all accounts profiles by just incrementing a ID in URL - and maybe other reason, but that is not the question)
But, I am worried about performance on registration.
It will be something like this:
while (RANDOM_ID is not taken): generate new RANDOM_ID
On generating a new ID for the new account, I will query database (MySQL) to check if the ID exists, for each generation.
Is there any better solution for this?
Is there any disadvantage of using random IDs?
Thanks in advance.
There are many, many reasons not to do this:
Your solution, as written, is not transactionally-safe; two transactions at the same time could both generate the same "random" ID.
If you serialize the transaction in order to make it safe, you will slaughter performance because the query will keep every single collision row locked until it finds a spare ID.
Using a random ID as the primary key will fragment the hell out of your clustered index. This is bad enough with uuids - the whole point of an auto-generated identity column is so you can generate a safe sequence out of it.
Why not use a regular primary key, but just don't use that in any of your URLs? Generate a secondary non-sequential ID along with it - such as a uuid - index it, and use this column in any public-facing segments of your application instead of the primary key if you are really worried about security.
You can use UUIDs. It's a unique identifier generated based partly on timestamp. It's almost certainly guaranteed to be unique so you don't have to do a query to check.
i do not know what language you're using, but there should be library or sample code for this for most languages.
Yes you can use UUID but keep your auto_increment field. Just add a new field and set it so something like: md5(microtime(true).rand()) or whatever other method you like and use that unike key along the site to make the links instead to expose the primary key in urls.

Resources