SQLite中的表格内的表格

时间:2018-07-24 15:43:41

标签: android android-sqlite multiple-tables

我实际上是在制作一个包含不包含任何详细信息的表格的应用程序。的商店。现在,我想为每个商店创建表,其中将包含事物/产品的详细信息。 现在的问题是商店列表不是固定的,用户可以根据需要添加任意数量的商店,因此对于我要以编程方式创建新表的每个新商店。

我已经用标准技术实现了带有固定表的标准表,该表具有预定义的名称和列。

我是Android的新手,请指导。

2 个答案:

答案 0 :(得分:1)

为了遵循规范并减少开销,看起来其他商店信息的表似乎不是必需的。只需创建一个带有商店详细信息的表,因为这些详细信息将是静态的/特定于商店。

但是,如果您为每个用户都有一个表,并且该用户将有一个可变的商店列表,那么您可能有一个用户表,然后是一个映射表/参考表/链接表,该表变成了很多对很多关系(即一个用户可以拥有许多商店,并且商店可以被引用/链接到许多用户)。

例如,您可能具有以下内容:-

DROP TABLE IF EXISTS users;
DROP TABLE IF EXISTS stores;
DROP TABLE IF EXISTS user_store_reference;
CREATE TABLE IF NOT EXISTS users (_id INTEGER PRIMARY KEY, user_name TEXT, user_email, TEXT, user_password TEXT);
CREATE TABLE IF NOT EXISTS stores(_id INTEGER PRIMARY KEY, store_name TEXT, store_address TEXT);
CREATE TABLE IF NOT EXISTS user_store_reference (user_reference INTEGER, store_reference INTEGER, PRIMARY KEY(user_reference,store_reference));

INSERT INTO users (user_name,user_email,user_password) VALUES
    ('Fred','fred@xmail.moc','1234567890'), -- will be id `
    ('Bert','bert@noemail.net','0987654321'), -- will be id 2
    ('Mary','mary@hotmail.com','11111111') -- will be id 3
;
INSERT INTO Stores (store_name,store_address) VALUES
    ('The Corner Store','1 The Corner, Squaretown'), -- will be id 1
    ('Smiths','10 Somewhere Street, Noweheretown'), -- will be id 2
    ('Cottons','4 Wool Street, Fabrictown'), -- will be id 3
    ('Stringers','114 High Street, Noweheretown') -- will be id 4
;
INSERT INTO user_store_reference VALUES
    (1,2), -- Fred has store Smiths
    (1,4), -- Fred also has store Stringers
    (3,1), -- Mary has store The Corner Store
    (3,2), -- Mary also has store Smiths
    (3,3), -- Mary also has store Cottons
    (2,2), -- Bert has store Smiths
    (2,3), -- Bert has store Cottons
    (2,1), -- Bert has store The Corner Store
    (2,4) -- Bert has store Stringers
;

SELECT user_name, count() AS store_count, group_concat(store_name,' - ') 
FROM users 
JOIN user_store_reference ON user_reference = users._id 
JOIN stores ON stores._id = store_reference
GROUP BY users._id ORDER BY count() ASC
;

最后的查询将提供每个用户的商店数量的概述以及这些商店的列表(例如,如何链接/映射/引用又称为 JOIN 获得结果):-

enter image description here

Android上的等效内容

可以使用以下代码将以上内容翻译为Android:-

数据库帮助程序类DBHelper.java

在Android上使用SQLite的常见方法是利用 SQLiteOpenHelper 类的子类。以下是此类的示例(通常称为数据库助手):-

public class DBHelper extends SQLiteOpenHelper {

    public static final String DBNAME = "StoresAppDB";
    public static final int DBVERSION = 1;

    public static final String TB_USERS = "users";
    public static final String TB_STORES = "stores";
    public static final String TB_USERSTOREMAP = "user_store_reference";

    public static final String COL_USERS_ID = BaseColumns._ID;
    public static final String COL_USERS_NAME = "user_name";
    public static final String COL_USERS_EMAIL = "user_email";
    public static final String COL_USERS_PASSWORD = "user_password";

    public static final String COL_STORES_ID = BaseColumns._ID;
    public static final String COL_STORES_NAME = "store_name";
    public static final String COL_STORES_ADDRESS = "store_address";

    public static final String COL_USERSTOREMAP_USERREF = "user_reference";
    public static final String COL_USERSTOREMAP_STOREREF = "store_reference";

    SQLiteDatabase mDB;

    public DBHelper(Context context) {
        super(context, DBNAME, null, DBVERSION);
        mDB = this.getWritableDatabase();
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        String tblcrt_base = "CREATE TABLE IF NOT EXISTS ";
        String id_col_def = " INTEGER PRIMARY KEY, ";
        String users_crtsql = tblcrt_base + TB_USERS + "(" +
                COL_USERS_ID + id_col_def +
                COL_USERS_NAME + " TEXT, " +
                COL_USERS_EMAIL + " TEXT," +
                COL_USERS_PASSWORD + " TEXT " +
                ")";
        String stores_crtsql = tblcrt_base + TB_STORES + "(" +
                COL_STORES_ID + id_col_def +
                COL_STORES_NAME + " TEXT, " +
                COL_STORES_ADDRESS + " TEXT" +
                ")";
        String userstore_crtsql = tblcrt_base + TB_USERSTOREMAP + "(" +
                COL_USERSTOREMAP_USERREF + " INTEGER, " +
                COL_USERSTOREMAP_STOREREF + ", " +
                " PRIMARY KEY (" +
                COL_USERSTOREMAP_USERREF +
                "," +
                COL_USERSTOREMAP_STOREREF +
                ")" +
                ")";
        db.execSQL(users_crtsql);
        db.execSQL(stores_crtsql);
        db.execSQL(userstore_crtsql);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int i, int i1) {

    }

    public long addUser(String name, String email, String password) {
        ContentValues cv = new ContentValues();
        cv.put(COL_USERS_NAME,name);
        cv.put(COL_USERS_EMAIL,email);
        cv.put(COL_USERS_PASSWORD,password);
        return mDB.insert(TB_USERS,null,cv);
    }

    public long addStore(String name, String address) {
        ContentValues cv = new ContentValues();
        cv.put(COL_STORES_NAME,name);
        cv.put(COL_STORES_ADDRESS,address);
        return mDB.insert(TB_STORES,null,cv);
    }

    public long addUserStoreMapping(long user, long store) {
        ContentValues cv = new ContentValues();
        cv.put(COL_USERSTOREMAP_USERREF,user);
        cv.put(COL_USERSTOREMAP_STOREREF,store);
        return mDB.insert(TB_USERSTOREMAP,null,cv);
    }

    /*
        SELECT users._id, user_name, count() AS store_count, user_name||' has stores '||group_concat(store_name,' - ')
        FROM users
        JOIN user_store_reference ON user_reference = users._id
        JOIN stores ON stores._id = store_reference
        GROUP BY users._id ORDER BY count() ASC
        ;
     */
    public static final String DCOL_COUNT = "store_count";
    public static final String DCOL_USERANDSTORES = "user_and_stores";
    public Cursor getUserStoreUsage() {
        String[] columns = new String[]{
                TB_USERS + "." + COL_USERS_ID,
                COL_USERS_NAME,
                "count() AS " + DCOL_COUNT,
                COL_USERS_NAME + "||' has stores '||group_concat(" + COL_STORES_NAME + ",' - ') AS " + DCOL_USERANDSTORES
        };
        String tables =
                TB_USERS +
                        " JOIN " + TB_USERSTOREMAP + " ON " + COL_USERSTOREMAP_USERREF + "=" + TB_USERS + "." + COL_USERS_ID +
                        " JOIN " + TB_STORES + " ON " + TB_STORES + "." + COL_STORES_ID + "=" + COL_USERSTOREMAP_STOREREF
                ;
        return mDB.query(tables,columns,null,null,TB_USERS+"."+COL_USERS_ID,null,"count() ASC");
    }
}

这包括:-

  • 创建数据库时创建表。
  • 促进添加行的方法
  • 一种方法getUserStoreUsage()返回具有用户/商店信息(将通过列表视图列出)的游标。这类似于上面的查询。
    • 注意,作为光标适配器的行正在使用名为 _id 的行(因此使用 BaseColumns._ID 等同于 { {1}}

调用活动_id

公共类MainActivity扩展了AppCompatActivity {

MainActivity.java

}

结果:-

enter image description here

答案 1 :(得分:0)

您将需要更好地了解表之间的关系。

我的SQL-fu有点生锈,但这是多个存储数据库的肮脏快速示例。

因此,您在store表中添加了ID和商店名称(我忘记添加了)。

然后,您将拥有详细信息表(其中具有该商店的详细信息)

然后将这两个表与中间表(称为StoreDetails)连接起来。

如果您想深入学习如何打破数据库中的多对多关系,快速的Google搜索将带来很多示例。

enter image description here