Get index list for a table in Sybase - z-index

This link contains the answer to the question, but it is not completed.
A Sybase DBMS has a notion of catalogs and schemas. So, how do I write a query to retrieve list of indexes for a table inside schema that is inside catalog?
[EDIT]
Consider following scenario:
USE test
GO
CREATE TABLE dbo.test_table(<field_list>)
GO
CREATE TABLE foo.test_table(<field_list>)
GO
CREATE INDEX test_index ON test_table(<index_field_list>)
GO
As you can see there are 2 test_table tables created: one in the schema called dbo and one in the schema called foo. And so now my question would be - how do I write a query that properly check for existence of the index on the table test_table in the schema foo? Because the link I referenced does not differentiate between those 2 tables and therefore will fail in this case. I very much prefer to filter schema and table names rather than using schemaName.tableName format. I hope you get an idea. If not please let me know and I will try to explain with even further details.
[/EDIT]

If you're signed into the test database as user foo, the create index command will be applied against the foo.test_table table (precedence is given to objects you own).
If you're signed into the test database as anyone other than foo, and assuming you have permissions to create an index, the create index command will be applied against the dbo.test_table table (precedence goes to objects owner by dbo if you don't own an object of the given name and you have not provided an explicit owner).
If you know you're going to have multiple tables with the same name but different owners, it's a bit more 'clean' to get in a habit of providing explicit owner names (and you're less likely to issue a command against the 'wrong' table).
As for how to check for the existence of an index ... in a nutshell:
sysusers contains db user names and ids (name, uid)
sysobjects contains object names, object types, object ids and owner ids (name, type, id, uid)
sysindexes contains index names, object ids, index ids, and a denormalized list of columns that make up the index (name, id, indid, keys1/keys2)
syscolumns contains column names for tables/procs/views, object ids, column ids (name, id, colid)
Sample joins (using old style join clauses):
select ....
from sysusers u,
sysobjects o,
sysindexes i
where u.name = '<user_name>'
and o.name = '<table_name>'
and o.type = 'T' -- T=table, P=procedure, V=view
and i.name = '<index_name>'
and o.uid = u.uid
and o.id = i.id
The join from sysindexes.keys1/keys2 to syscolumns.colid is a bit convoluted as you need to figure out how you wish to parse the keys1/keys2 columns to obtain individual syscolumns.colid values.
Again, I'd suggest you take a look at the code for the sp_helpindex stored proc as it references all of the appropriate system (aka catalog) tables and includes examples of the necessary join clauses:
exec sybsystemprocs..sp_helptext sp_helpindex,null,null,'showsql'
go

Related

What data type is used for saving lists in sqlite3 using Python?

As long as I know, there are only five data types that can be set to columns in a sqlite3 table. They are:
null means no data.
integer means a whole number.
real means a float.
text means any string.
blob a binary data field in which you can store files, documents, images.
But currently, I have a list called self. inventory in my code, that gets items added into it occasionally when users' do something specific. That is not the issue. My problem is that what data type should I assign to the list that I want to store in the table? Or is there any other method I can use to store the values of the table into the db. Currently, here is my connection, cursor and table execution:
connection = sqlite3.connect('db_of_game.db')
cursor = connection.cursor()
cursor.execute(
'CREATE TABLE user_data(user_name text primary key, money integer, inventory <What data type to use here?>, deposited integer, allowed_deposit integer)'
)
connection.commit()
connection.close()
Assuming each item can only belong to a single user, you'd use a one-to-many pattern. Many items, one user. Items have their own table and they refer to their user.
create items (
id integer primary key,
name text not null,
user_name text not null references user_data(user_name)
)
(Note: Using a username as a primary key is to be avoided. Usernames change. Primary keys cannot change. They also require more storage and comparison time. Instead, use a simple integer. In SQLite integer primary key works.)
Then to get all a user's items...
select items.name
from items
where user_name = ?
If each item can belong to many users, that is a many-to-many relationship and you need a join table to link users to items.
create items (
id integer primary key,
name text not null
)
create inventory (
item_id integer not null references items(id),
user_name text not null references user_data(user_name)
)
And to get a user's inventory you check inventory to get the item IDs and join with items to get the item name.
select items.name
from items
join inventory on items.id = inventory.item_id
where inventory.user_name = ?
This might seem convoluted, but this is how a relational database works. By setting up relationships between items. It takes a bit to wrap your head around, but it's worth it. It makes searching very fast. If you used a comma separated list and want to find the users with a certain item, you need to look at every user and parse their list. Now you just query the items table. If items.name is indexed it will not have to search the whole table.
select *
from items
where item.name like ?
For more...
W3Schools - SQL Joins
Visual representation of SQL joins
TutorialsPoint - Using Joins
TutorialsPoint - Indexes

passing variables in cur.executescript

Currently I have the following code which checks if tablename "Company" exists in the database, and then creates the table with the given fields.
cur.executescript('''
DROP TABLE IF EXISTS Company;
CREATE TABLE Company (
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,
name VARCHAR2
)
''')
I want to make this query generic as in, instead of just using "Company" in my query, I need to take the names from a list. Is it possible to pass a variable in the query instead of passing "Company" in this example.
Thank you!
It is not possible to pass a variable table name (or column name) to sqlite. (And since executescript takes exactly one argument, it's not possible to pass a variable to executescript).
You could build the query before the execute and pass that variable to executescript.
And of course if you take the table names from a list, it seems likely you will have to take the column names too!

Cassandra : Using output of one query as input to another query

I have two tables one is users and other is expired_users.
users columns-> id, name, age
expired_users columns -> id, name
I want to execute the following query.
delete from users where id in (select id from expired_users);
This query works fine with SQL related databases. I want find a solution to solve this in cassandra.
PS: I don't want to add any extra columns in the tables.
While designing cassandra data model, we cannot think exactly like RDBMS .
Design like this --
create table users (
id int,
name text,
age int,
expired boolean static,
primary key (id,name)
);
To mark a user as expired -- Just insert the same row again
insert into users (id,name,age,expired) values (100,'xyz',80,true);
you don't have to update or delete the row, just insert it again, previous column values will get overridden.
What you want to is to use join as a filter for your delete statement, and this is not what the Cassandra model is built for.
AFAIK there is no way to perform this using cql. If you want to perform this action without changing the schema - run external script in any language that has drivers for Cassandra.

Cassandra Hierachy Data Model

I'm newbie design cassandra data model and I need some help to think out the box.
Basically I need a hierarchical table, something pretty standard when talking about Employee.
You have a employee, say Big Boss, that have a list of employee under him.
Something like:
create table employee(id timeuuid, name text, employees list<employee>, primary key(id));
So, is there a way to model a hierarchical model in Cassandra adding the table type itself, or even another approach?
When trying this line above it give me
Bad Request: line 1:61 no viable alternative at input 'employee'
EDITED
I was thinking about 2 possibilities:
Add an uuid instead and in my java application find each uuid Employee when bringing up the "boss".
Working with Map, where the uuid is the id itself and my text would be the entire Row, then in my java application get the maps, convert each "text" employee into a Employee entity and finally return the whole object;
It really depends on your queries...one particular model would only be good for a set of queries, but not others.
You can store ids, and look them up again at the client side. This means n extra queries for each "query". This may or may not be a problem, as queries that hit a partition are fast. Using a map from id to name is also an option. This means you do extra work and denormalise the names into the map values. That's also valid. A third option is to use a UDT (user defined type). You could then have a list or set or even map. In cassandra 2.1, you could index the map keys/ values as well, allowing for some quite flexible querying.
https://www.datastax.com/documentation/cql/3.1/cql/cql_using/cqlUseUDT.html
One more approach could be to store a person's details as id, static columns for their attributes, and have "children" as columns in wide row format.
This could look like
create table person(
id int primary key,
name text static,
age int static,
employees map<int, employeeudt>
);
http://www.datastax.com/documentation/cql/3.1/cql/cql_reference/refStaticCol.html
Querying this will give you rows with the static properties repeated, but on disk, it's still held once. You can resolve the rest client side.

Shoudl I create seperate column family if I want to query on many columns ? or use composite PK?

I have a column family like
object
(
obect_id,
company-id,
group_id,
family_id,
description,
..
);
I want to query that based on object id, company id ,group id and any combination of these.
My question is
should i make composite primary key
(object id, company id ,group id)
or create seperate column familis ?
only object id is unique in CF, company id can repeat in multiple rows, but group iddoes not repeat in many rows
You may well want to duplicate your data in multiple CFs depending on your query patterns. This is quite common practice.
If a common query is "Get all objects by company_id" then you might want to store all objects with in a CF with partitioned just by company_id as a row key. If you need to do individual object lookups as well, then you store that data duplicated in another CF - each object partitioned by object_id. If groups are always a subset of a specific company, perhaps you want to row key by company, but then cluster by group.
You should be designing your Cassandra schema based on the queries you need to run, rather than the data that needs to go in it.

Resources