精华内容
下载资源
问答
  • 数据存储 使用场景 许多时候我们需要将用户的数据保存到本地,以便以后的调用。比如说openid,如果每次打开小程序都需要发送code到后台解析成出openid,对资源消耗还是比较大的。这个时候数据缓存就派上了用场。 ...

    安卓和小程序体验

    小程序体验

    安卓版本体验 安卓体验download

    数据存储

    使用场景

    许多时候我们需要将用户的数据保存到本地,以便以后的调用。比如说openid,如果每次打开小程序都需要发送code到后台解析成出openid,对资源消耗还是比较大的。这个时候数据缓存就派上了用场。

    两种数据缓存

    1.wx.setStorageSync(string key, any data)

    2.wx.setStorage(Object object)

    两种都可以实现缓存数据,区别就在于同步和异步

    以Sync(同步,同时)结尾的都是都是同步缓存,二者的区别是,异步不会阻塞当前任务,同步缓存直到同步方法处理完才能继续往下执行。
        通俗点说,异步就是不管保没保存成功,程序都会继续往下执行.同步是等保存成功了,才会执行下面的代码.
        使用异步,性能会更好;而使用同步,数据会更安全
        一般都使用同步,异步是为了用户体验的情况而选择,同步相对简单。

    wx.setStorage(Object object)

    将数据存储在本地缓存中指定的 key 中。会覆盖掉原来该 key 对应的内容。除非用户主动删除或因存储空间原因被系统清理,否则数据都一直可用。单个 key 允许存储的最大数据长度为 1MB,所有数据存储上限为 10MB。

    参数

    Object object

    属性 类型 默认值 必填 说明
    key string   本地缓存中指定的 key
    data any   需要存储的内容。只支持原生类型、Date、及能够通过JSON.stringify序列化的对象。
    success function   接口调用成功的回调函数
    fail function   接口调用失败的回调函数
    complete function   接口调用结束的回调函数(调用成功、失败都会执行)

    示例代码

    wx.setStorage({
      key:"key",
      data:"value"
    })
    
    try {
      wx.setStorageSync('key', 'value')
    } catch (e) { }

    wx.setStorageSync(string key, any data)

    wx.setStorage 的同步版本

    参数

    string key

    本地缓存中指定的 key

    any data

    需要存储的内容。只支持原生类型、Date、及能够通过JSON.stringify序列化的对象。

    示例代码

    wx.setStorage({
      key:"key",
      data:"value"
    })
    
    try {
      wx.setStorageSync('key', 'value')
    } catch (e) { }
    展开全文
  • Android五大数据存储

    千次阅读 多人点赞 2019-01-15 17:30:07
    数据存储可谓是Android中灰常灰常重要的一部分了。任何一个应用离不开数据的存储,有时需内存存储,有时需本地存储,还有时需要两个进程间传输数据,等等。那接下来介绍的五大存储中将包括了所有的应用中可能遇到的...

    前言

    数据存储可谓是Android中灰常灰常重要的一部分了。任何一个应用离不开数据的存储,有时需内存存储,有时需本地存储,还有时需要两个进程间传输数据,等等。那接下来介绍的五大存储中将包括了所有的应用中可能遇到的存储情况。

    一、SharedPreference存储

    (1)什么是SharedPreference存储

    SP存储是一种轻量级的数据存储,通常做一些简单,单一数据的持久化缓存
    (2)SharedPreference存储的特点

    SharedPreference保存的数据是简单的key--value键值对。保存的数据是以xml文件的格式存储的。

    可设置数据只能是当前应用读取,而别的应用不可以

    应用卸载时会删除此数据
    (3)SharedPreference的作用

    SharedPreference存储倾向于保存用户偏好设置,比如某个Checkbox的选择状态,用户登录的状态,配置信息,实现记住密码功能等。

    (4)SharedPreference存储的数据类型

    boolean float  int  long String  

    (5)数据保存的路径

    /data/data/packageName/shared_prefs/yyy.xml

    (6)SharedPreference的使用

    SharedPreferences只是个接口,而真正的实现是SharedPreferencesImpl,我们后续的get,put操作实际也是通过SharedPreferencesImpl对象完成的。

    Editor也是一个接口,我们一系列的put操作,还有clear,remove,apply,commit都是在EditorImpl对象中。

           ①.获取SharedPreference的对象,通过getSharedPreference(String,int)方法。第一个参数用于指定该存储文件的名称,不用加后缀,第二个参数指定文件的操作模式。一般用MODE_PRIVATE 私有方式存储,其他应用无法访问。

           ②.设置参数,必须通过一个SharedPreference.Editor对象。存储键值对。只能存放Boolean,Float,Int,Long,String 五种类型。editor.putXxx("key","value")。

           ③.通过editor.commit()提交数据。也可以通过clean(),remove()清除。

           ④.数据存储在Android系统的 /data/data/"app package name"/shared_prefs 目录下的一个.xml文件。

    (7)简单例子实现SharedPreference存储用户信息的代码:

    布局:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:context="com.example.wcystart.otherproject.MainActivity">
    
        <EditText
            android:id="@+id/et"
            android:layout_marginTop="20dp"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            />
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:layout_marginTop="20dp">
            <Button
                android:id="@+id/input"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="存储"
                android:onClick="writeInfo"/>
            <Button
                android:id="@+id/output"
                android:layout_marginLeft="10dp"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="读取"
                android:onClick="readInfo"/>
        </LinearLayout>
        <TextView
            android:id="@+id/showtext"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="20dp"
            android:layout_marginLeft="15dp"
            android:text="存储的信息"
            android:textSize="25dp"/>
    
    </LinearLayout>
    

    Activity:

    
    public class DataActivity extends AppCompatActivity {
        private EditText mEt;
        private Button mInput;
        private Button mOutput;
        private TextView mShowText;
        private SharedPreferences mSp;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_data);
            mEt = findViewById(R.id.et);
            mInput = findViewById(R.id.input);
            mOutput = findViewById(R.id.output);
            mShowText = findViewById(R.id.showtext);
            mSp=super.getSharedPreferences("yan",MODE_PRIVATE);
    
        }
        //存数据
        public void writeInfo(View view) {
          SharedPreferences.Editor editor=mSp.edit();
          editor.putString("name",mEt.getText().toString());
          editor.commit();
          //editor.apply();
            Toast.makeText(this,"存储数据成功",Toast.LENGTH_LONG).show();
        }
        //读数据
        public void readInfo(View view) {
            String info = mSp.getString("name", "");
            mShowText.setText(info);
            Toast.makeText(this,"读取数据成功",Toast.LENGTH_LONG).show();
        }
    }

    运行结果图:

    (8)如何查看/data/data/应用包名/shared_prefs/yyy.xml呢?

    之前我们查看Android手机中文件系统前提条件是root手机,然后去DDMS里边去看,觉得挺麻烦的。但是现在AndroidStudio大多都更新到3.0及以上版本之后,就非常简单了,还不用root手机。

    补充:root的意思:root是手机系统的最高权限,这和我们电脑windows操作系统类似,我们知道电脑windows系统最高管理权限是用户管理员(administraror),而手机系统最高权限是root用户。有了root权限之后呢,可以轻松安装与卸载任何手机应用,包括系统原来厂商安装的,后期使用无法卸载的程序,获取到root权限之后全部均能卸载与删除。

    查看步骤:

    1、手机USB线连接手机,打开调试模式

    2、打开AS,找到窗口右下角的Device File Explorer,如下图:

    接下来我们查看下shared_prefs

     看到没,yan.xml,就是SP存储是以xml文件的格式存储的数据,yan这个名字就是

    即我们创建时传入的name,系统源码根据name去创建一个File

    打开看看yan.xml中的内容是什么样的呢?

    <?xml version='1.0' encoding='utf-8' standalone='yes' ?>
    <map>
        <string name="name">wcystart</string>
    </map>
    

      看到这,我们大致了解,Sp存储的数据会在本地生成一个.xml文件,并将该文件的数据存储在一个map对象中。

    (9)SharedPreference使用时应注意到的地方

    在修改数据之后除了选择commit提交之外,还可以使用apply进行提交,那有什么区别呢?

    commit提交发生在UI主线程,而apply发生在工作线程。但是apply也不一定是安全的

    当我们首次创建SharedPreferences对象时,会根据文件名将文件下内容一次性加载到mMap容器中,每当我们edit都会创建一个新的EditorImpl对象,当修改或者添加数据时会将数据添加到mModifiled容器中,然后commit或者apply操作比较mMap与mModifiled数据修正mMap中最后一次提交数据然后写入到文件中。而get直接从mMap中读取。试想如果此时你存储了一些大型key或者value它们会一直存储在内存中得不到释放。

    正确使用的建议:

    1、不要存放大的key和value在SharedPreferences中,否则会一直存储在内存中得不到释放,内存使用过高会频发引发GC,导致界面丢帧甚至ANR。

    2、不相关的配置选项最好不要放在一起,单个文件越大读取速度则越慢。

    3、读取频繁的key和不频繁的key尽量不要放在一起(如果整个文件本身就较小则忽略,为了这点性能添加维护得不偿失)。

    4、不要每次都edit,因为每次都会创建一个新的EditorImpl对象,最好是批量处理统一提交。

    否则edit().commit每次创建一个EditorImpl对象并且进行一次IO操作,严重影响性能。

    5、commit发生在UI线程中,apply发生在工作线程中,对于数据的提交最好是批量操作统一提交。虽然apply发生在工作线程(不会因为IO阻塞UI线程)但是如果添加任务较多也有可能带来其他严重后果(参照ActivityThread源码中handleStopActivity方法实现)。

    6、尽量不要存放json和html,这种可以直接文件缓存。

    7、不要指望这货能够跨进程通信 Context.PROCESS 。

    8、最好提前初始化SharedPreferences,避免SharedPreferences第一次创建时读取文件线程未结束而出现等待情况。

    参考文章链接https://www.jianshu.com/p/8eb2147c328b/  从源码的角度去看SharedPreference

    (10)不能滥用SharedPrefreence

    一个默认的Sp有90K,所以不要在sp里边存储超级大的key,因为在getSharedPreference的时候会把所有的sp放到一个静态变量里边缓存起来:这个static的sSharedPrefsCache,它保存了你所有使用的sp,然后sp里面有一个成员mMap保存了所有的键值对;这样,你程序中使用到的那些个sp永远就呆在内存中。

    存储json等特殊符号很多的value

    如果在sp里边存json或者是Html,这么做也不是不可以,但是如果这个json串相对较大的话,也会引起sp读取速度下降~

    JSON或者HTML格式存放在sp里面的时候,需要转义,这样会带来很多 & 这种特殊符号,sp在解析碰到这个特殊符号的时候会进行特殊的处理,引发额外的字符串拼接以及函数调用开销。而JSON本来就是可以用来做配置文件的,你干嘛又把它放在sp里面呢?多此一举。

    多次edit 多次apply

    多次edit的话会创建多个Editor对象,额外占用内存。如果多次apply的话会造成页面卡顿~

    1. 不要存放大的key和value!我就不重复三遍了,会引起界面卡、频繁GC、占用内存等等,好自为之!
    2. 毫不相关的配置项就不要丢在一起了!文件越大读取越慢,不知不觉就被猪队友给坑了;蓝后,放进defalut的那个简直就是愚蠢行为!
    3. 读取频繁的key和不易变动的key尽量不要放在一起,影响速度。(如果整个文件很小,那么忽略吧,为了这点性能添加维护成本得不偿失)
    4. 不要乱edit和apply,尽量批量修改一次提交!
    5. 尽量不要存放JSON和HTML,这种场景请直接使用json!
    6. 不要指望用这货进行跨进程通信!!!

    (11)为什么说SP是一种轻量级数据存储呢?

    由它的设计所决定;sp在创建的时候会把整个文件全部加载进内存,如果sp文件比较大,就会带来几个严重问题:

    1. 第一次从sp中获取值的时候,有可能阻塞主线程,使界面卡顿、掉帧。
    2. 解析sp的时候会产生大量的临时对象,导致频繁GC,引起界面卡顿。
    3. 这些key和value会永远存在于内存之中,占用大量内存。

    sp加载的是子线程,怎么会卡住主线程呢?子线程IO就一定不会阻塞主线程吗?

    下面是默认的sp实现SharedPreferenceImpl这个类的getString函数:

    public String getString(String key, @Nullable String defValue) {
        synchronized (this) {
            awaitLoadedLocked();
            String v = (String)mMap.get(key);
            return v != null ? v : defValue;
        }
    }

    继续看看这个awaitLoadedLocked:

    private void awaitLoadedLocked() {
        while (!mLoaded) {
            try {
                wait();
            } catch (InterruptedException unused) {
            }
        }
    }
    一把锁就是挂在那里!!这意味着,如果你直接调用getString,主线程会等待加载sp的那么线程加载完毕!这不就把主线程卡住了么?

     

    二、文件存储

    文件存储又分为手机内部存储和手机外部存储

    1.手机内部文件存储

    ①.对于存储的文件的类型没有要求:.txt  .doc   .png  .mp3 .avi
    ②.只要没有超出内部存储空间的大小即可
    ③.默认情况下,只能被当前应用读取.
    ④.存储的路径:data/data/应用包名/files/xxx.xx
    ⑤.会随着应用的卸载而被删除

    ep:下面的例子是将assets目录下的文件读取出来保存到手机内部存储中,然后在将文件从手机内部存储中读取出来显示在ImageView控件上

    布局

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:context="com.example.wcystart.otherproject.FileActivity">
    
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:padding="10dp"
            android:text="1.将assets下的logo.png保存到手机内部"
            android:textColor="@color/colorAccent"
            android:textSize="20sp" />
    
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="2.读取手机内部图片并显示"
            android:padding="10dp"
            android:textColor="@color/colorAccent"
            android:textSize="20sp" />
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            android:orientation="horizontal">
    
            <Button
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:onClick="save"
                android:text="保存"
                android:textSize="20dp" />
    
            <Button
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:onClick="read"
                android:text="读取"
                android:textSize="20dp" />
    
        </LinearLayout>
    
        <ImageView
            android:id="@+id/image"
            android:layout_width="wrap_content"
            android:layout_gravity="center"
            android:src="@mipmap/ic_launcher"
            android:paddingTop="10dp"
            android:layout_height="wrap_content" />
    </LinearLayout>
    

    Activity:

    public class FileActivity extends AppCompatActivity {
        private ImageView mImageView;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_file);
            mImageView = findViewById(R.id.image);
        }
    
        public void save(View view) {
            InputStream inputStream = null;
            FileOutputStream outputStream = null;
            //读取资产目录下的图片
            AssetManager assets = this.getAssets();
            try {
                inputStream = assets.open("logo.png");
    
                Log.i("TAG", this.getFilesDir().toString());
    
                outputStream = openFileOutput("logo.png", Context.MODE_PRIVATE);
                byte[] data = new byte[1024];
                int len;
                while ((len = inputStream.read(data)) != -1) {
                    outputStream.write(data, 0, len);
                }
                Toast.makeText(this, "保存成功", Toast.LENGTH_SHORT).show();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (outputStream != null) {
                    try {
                        outputStream.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (inputStream != null) {
                    try {
                        inputStream.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
    
        }
    
        public void read(View view) {
            Bitmap bitmap = null;
            try {
                bitmap = BitmapFactory.decodeStream(openFileInput("logo.png"));
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
            mImageView.setImageBitmap(bitmap);
        }

    android 中对文件的IO操作,OpenFileInput OpenFileOutput 返回对象为Java Io 的FileInputStream和FileOutputStream运行结果:

    文件存储的位置在哪呢,还是在data/data/包名/files目录下找

    2.手机外部存储

    路径一:storage/sdcard/Android/data/package/files/xxx

    路径二:storage/sdcard/xxx/xxx

    ①两个路径存储的文件,对文件类型没有要求。
    ②文件的大小只要不超出sd卡的存储空间即可
    ③两个路径下存储的文件不是私有的,其他应用可以访问。
    ④路径一:其下存储的文件会随着应用的卸载被删除
    ⑤路径二:其下存储的文件不会随着应用的卸载被删除

    需注意,必须保证sd卡挂载在手机上才能读写,否则不能操作

    ep:手机外部存储路径一 代码举例

    布局:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:context="com.example.wcystart.otherproject.SDCardActivity">
    
        <EditText
            android:id="@+id/et_fileName"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="输入文件名"
            android:padding="10dp"/>
        <EditText
            android:id="@+id/et_fileContent"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="输入文件内容"
            android:padding="10dp"/>
        <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
        <Button
            android:id="@+id/save1"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:onClick="save1"
            android:text="路径一保存"/>
        <Button
            android:id="@+id/read1"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:onClick="read1"
            android:text="路径一读取"/>
    </LinearLayout>
    
    </LinearLayout>
    

    Actiivty:

    package com.example.wcystart.otherproject;
    
    import android.os.Bundle;
    import android.os.Environment;
    import android.support.v7.app.AppCompatActivity;
    import android.view.View;
    import android.widget.EditText;
    import android.widget.Toast;
    
    import java.io.ByteArrayOutputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    
    public class SDCardActivity extends AppCompatActivity {
        private EditText mEtFileName;
        private EditText mEtFileContent;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_sdcard);
            mEtFileName = findViewById(R.id.et_fileName);
            mEtFileContent = findViewById(R.id.et_fileContent);
        }
    
        public void save1(View view) {
            if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { //sd卡处于挂载状态
                String fileName = mEtFileName.getText().toString();
                //获取要写入的文件目录  storage/sdcard/Android/data/包名/files/xxx
                File externalFilesDir = this.getExternalFilesDir(null);
                //创建指定目录下的文件
                File file = new File(externalFilesDir, fileName);
                //开始写文件
                FileOutputStream fos = null;
                try {
                    fos = new FileOutputStream(file);
                    //获取要写出的文件内容
                    String content = mEtFileContent.getText().toString();
                    fos.write(content.getBytes("UTF-8"));
                    Toast.makeText(this, "文件保存成功", Toast.LENGTH_LONG).show();
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    if (fos != null) {
                        try {
                            fos.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            } else {
                Toast.makeText(this, "找不到指定的SD卡", Toast.LENGTH_SHORT).show();
            }
        }
    
        public void read1(View view) {
            if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
                String fileName = mEtFileName.getText().toString();
                File externalFilesDir = this.getExternalFilesDir(null);
                File file = new File(externalFilesDir, fileName);
                if (file.exists()) {
                    //开始读
                    FileInputStream fis;
                    try {
                        fis = new FileInputStream(file);
                        //从输入流中读取内容
                        String content = readStringFromInputStream(fis);
                        mEtFileContent.setText(content);
                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                    }
                } else {
                    Toast.makeText(this, "该文件不存在", Toast.LENGTH_SHORT).show();
                }
            }
        }
    
        private String readStringFromInputStream(FileInputStream fis) {
            //方式一 可能会出现乱码
    //        String content = "";
    //        byte[] buffer = new byte[1024];
    //        int len;
    //        try {
    //            while ((len = fis.read(buffer)) != -1) {
    //                content += new String(buffer);
    //            }
    //        } catch (IOException e) {
    //            e.printStackTrace();
    //        }
            //方式二 避免出现乱码
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int len;
            try {
                while ((len = fis.read(buffer)) != -1) {
                    baos.write(buffer, 0, len);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
    
            return baos.toString();
    
        }
    }
    

    运行结果:

    再来看下文件hello.txt文件所在的路径在哪呢? storage/sdcard/Android/data/包名/files/hello.txt

    再来看下hello.txt的内容:直接双击就可以在AS中查看

    读取的话:就是输入刚才保存的文件名,然后点击读取,就可以读取出hello.txt文件中的内容显示在EditText中了。

     

    ep:路径二 代码演示:storage/sdcord/xxx

    布局:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:context="com.example.wcystart.otherproject.SDCardActivity">
    
        <EditText
            android:id="@+id/et_fileName"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="输入文件名"
            android:padding="10dp"/>
        <EditText
            android:id="@+id/et_fileContent"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="输入文件内容"
            android:padding="10dp"/>
        <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
        <Button
            android:id="@+id/save1"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:onClick="save1"
            android:text="路径一保存"/>
        <Button
            android:id="@+id/read1"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:onClick="read1"
            android:text="路径一读取"/>
    </LinearLayout>
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            android:orientation="horizontal">
            <Button
                android:id="@+id/save2"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:onClick="save2"
                android:text="路径二保存"/>
            <Button
                android:id="@+id/read2"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:onClick="read2"
                android:layout_weight="1"
                android:text="路径二读取"/>
        </LinearLayout>
    
    </LinearLayout>
    

    Activity:

    package com.example.wcystart.otherproject;
    
    import android.os.Bundle;
    import android.os.Environment;
    import android.support.v7.app.AppCompatActivity;
    import android.view.View;
    import android.widget.EditText;
    import android.widget.Toast;
    
    import java.io.ByteArrayOutputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    
    public class SDCardActivity extends AppCompatActivity {
        private EditText mEtFileName;
        private EditText mEtFileContent;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_sdcard);
            mEtFileName = findViewById(R.id.et_fileName);
            mEtFileContent = findViewById(R.id.et_fileContent);
        }
    
        public void save2(View view) {
            if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { //sd卡处于挂载状态
                String fileName = mEtFileName.getText().toString();
                //获取要写入的文件目录  storage/sdcard/xxx
                String externalFilesDir = Environment.getExternalStorageDirectory().toString()+ "/wcystart";
                //创建文件目录
                File fileDir = new File(externalFilesDir);
                if (!fileDir.exists()) {
                    fileDir.mkdirs();
                    System.out.println("文件目录创建成功!!!");
                }
                //创建指定目录下的文件
                File file=new File(fileDir,fileName);
                //开始写文件
                FileOutputStream fos = null;
                try {
                    fos = new FileOutputStream(file);
                    //获取要写出的文件内容
                    String content = mEtFileContent.getText().toString();
                    fos.write(content.getBytes("UTF-8"));
                    Toast.makeText(this, "文件保存成功", Toast.LENGTH_LONG).show();
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    if (fos != null) {
                        try {
                            fos.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            } else {
                Toast.makeText(this, "找不到指定的SD卡", Toast.LENGTH_SHORT).show();
            }
        }
    
        public void read2(View view) {
            if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
                String fileName = mEtFileName.getText().toString();
                String externalFilesDir = Environment.getExternalStorageDirectory().toString() + "datastorgae";
                File fileDir=new File(externalFilesDir);
                File file = new File(fileDir, fileName);
                if (file.exists()) {
                    //开始读
                    FileInputStream fis;
                    try {
                        fis = new FileInputStream(file);
                        //从输入流中读取内容
                        String content = readStringFromInputStream(fis);
                        mEtFileContent.setText(content);
                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                    }
                } else {
                    Toast.makeText(this, "该文件不存在", Toast.LENGTH_SHORT).show();
                }
            }
        }
    
        private String readStringFromInputStream(FileInputStream fis) {
            //方式一 可能会出现乱码
    //        String content = "";
    //        byte[] buffer = new byte[1024];
    //        int len;
    //        try {
    //            while ((len = fis.read(buffer)) != -1) {
    //                content += new String(buffer);
    //            }
    //        } catch (IOException e) {
    //            e.printStackTrace();
    //        }
            //方式二 避免出现乱码
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int len;
            try {
                while ((len = fis.read(buffer)) != -1) {
                    baos.write(buffer, 0, len);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
    
            return baos.toString();
    
        }
    }
    

    运行结果报:

    也就是说:Environment.getExternalStorageDirectory().toString()或者是Environment.getExternalStorageDirectory().getPath()打印出来的路径是:/storage/emulated/0是找不到的,是因为现在的手机内存都不带SD卡了所以才找不到的么,。。。只是猜想

    如何使用手机内部存储和外部存储?

     *  1.如果涉及到的数据是私有的,则选择手机内部存储
     *  2.如果涉及到的数据不大,但是访问较频繁,则选择手机内部存储
     *  3.如果涉及到的数据较大,则考虑使用外部存储
     *  4.如果数据希望随着应用的卸载,而被删除,且不是私有的,则使用路径1
     *  5.如果数据希望随着应用的卸载,而不被删除,则使用路径2

    三、Sqlite数据库存储

    1.什么是Sqlite存储

    Sqlite:是一款嵌入式的轻型的关系型数据库

    2.Sqlite的特点

    ①安装文件小,最小只有几百K,Android系统已经安装

    ②支持多操作系统:Android,IOS ,Window,Linux等

    ③支持多语言:比如Java,PHP,C#

    ④处理速度快:处理速度比MySql、Oracle、SqlServer都要快(数据量不是太大的时候)

    ⑤存储结构型、关系型数据,可使用Sql语言,支持事物处理、独立无需服务进程

    3.Sqlite支持的数据类型与Mysql相似,常用的数据类型有:

    3.Sqlite的使用

    (1)自定义SqLiteOpenHelper类

    package com.example.wcystart.otherproject;
    
    import android.content.Context;
    import android.database.sqlite.SQLiteDatabase;
    import android.database.sqlite.SQLiteOpenHelper;
    
    /**
     * Created by ${wcystart}
     * date:on 2019/1/15
     * description:
     */
    
    public class DBHelper extends SQLiteOpenHelper {
    
        public DBHelper(Context context,int version){
            super(context,"student.db",null,version);
        }
        /**
         *
         * @param context:用于创建数据库的上下文
         * @param name:创建数据库的名称
         * @param factory:用户创建Cursor的工厂
         * @param version:数据库的版本
         */
        public DBHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
            super(context, name, factory, version);
        }
    
        /**
         * 当数据库首次创建的时候调用
         * @param db 可用来创建表(table)视图(view)索引(index)序列(sequence)触发器(trigger)存储函数 function 存储过程  producer
         */
        @Override
        public void onCreate(SQLiteDatabase db) {
            String sql="create table user(_id integer primary key autoincrement,name varchar,balance double)";
            db.execSQL(sql);
    
            //给表中添加两条数据
            db.execSQL("insert into user(name,balance)values('Tom',1000)");
            db.execSQL("insert into user(name,balance)values('Jerry',1000)");
    
        }
    
        /***
         * 当数据库升级的时候回调的方法
         * @param db
         * @param oldVersion
         * @param newVersion
         */
        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    
        }
    }

    在Activity中完成增删改查

    布局:

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingTop="10dp"
        tools:context=".DBActivity">
        
        <Button
            android:id="@+id/upgrade"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:text="更新数据库" />
    
        <Button
            android:id="@+id/insert"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@+id/upgrade"
            android:layout_centerHorizontal="true"
            android:text="插入数据" />
    
        <Button
            android:id="@+id/modify"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@+id/insert"
            android:layout_centerHorizontal="true"
            android:text="修改数据" />
        
        <Button
            android:id="@+id/query"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@+id/modify"
            android:layout_centerHorizontal="true"
            android:text="查询数据" />
    
        <Button
            android:id="@+id/delete"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@+id/query"
            android:layout_centerHorizontal="true"
            android:text="删除数据" />
    
    
        <Button
            android:id="@+id/delete_database"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@+id/delete"
            android:layout_centerHorizontal="true"
            android:text="删除数据库" />
        
    </RelativeLayout>
    public class DBActivity extends AppCompatActivity implements View.OnClickListener {
        private Button insert;
        private Button upgrade;
        private Button modify;
        private Button delete;
        private Button query;
        private Button delete_database;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_db);
    
            insert = findViewById(R.id.insert);
            upgrade = findViewById(R.id.upgrade);
            modify = findViewById(R.id.modify);
            delete = findViewById(R.id.delete);
            query = findViewById(R.id.query);
            delete_database =findViewById(R.id.delete_database);
    
            insert.setOnClickListener(this);
            upgrade.setOnClickListener(this);
            modify.setOnClickListener(this);
            delete.setOnClickListener(this);
            query.setOnClickListener(this);
            delete_database.setOnClickListener(this);
    
        }
    
        @Override
        public void onClick(View v) {
            switch (v.getId()){
                case R.id.insert: //增
                    DBHelper dbHelper = new DBHelper(this, 4);
                    SQLiteDatabase database = dbHelper.getReadableDatabase();
                    String sql = "insert into user(name,balance)values('Jane',40000)";
                    database.execSQL(sql);
                    dbHelper.close();
                    Toast.makeText(DBActivity.this, "添加成功", Toast.LENGTH_SHORT).show();
                    break;
                case R.id.upgrade://数据库升级
                    DBHelper upgrade_dbHelper = new DBHelper(this, 4);
                    SQLiteDatabase upgrade_database = upgrade_dbHelper.getReadableDatabase();
                    break;
                case R.id.modify: //改
                    DBHelper modify_dbHelper = new DBHelper(this, 4);
                    SQLiteDatabase modify_database = modify_dbHelper.getReadableDatabase();
                    ContentValues values = new ContentValues();
                    values.put("balance", 800);
                    //这个updateCount的意思是修改了几条
                    int updateCount = modify_database.update("user", values, "_id=?", new String[]{6 + ""});
                    Toast.makeText(DBActivity.this, "修改成功,修改了" + updateCount + "几条", Toast.LENGTH_SHORT).show();
    
                    modify_dbHelper.close();
                    break;
                case R.id.delete://删
                    DBHelper delete_dbHelper = new DBHelper(this, 4);
                    SQLiteDatabase delete_database = delete_dbHelper.getReadableDatabase();
                    int deleteCount = delete_database.delete("user", "_id=?", new String[]{"3"});
    
                    delete_dbHelper.close();
                    Toast.makeText(DBActivity.this, "删除成功,一共删除了" + deleteCount + "几条", Toast.LENGTH_SHORT).show();
                    break;
                case R.id.query://查
                    DBHelper query_dbHelper = new DBHelper(this, 4);
                    SQLiteDatabase query_database = query_dbHelper.getReadableDatabase();
                    //select ... from ... where .. group by ... having ... order by ... limit...
                    //返回游标,类似于jdbc中的结果集:ResultSet
                    Cursor cursor = query_database.query("user", null, null, null, null, null, null, null);
                    while(cursor.moveToNext()){//①判断下一行是否还有数据②如果返回true,指针下移
                        int id = cursor.getInt(cursor.getColumnIndex("_id"));
                        String name = cursor.getString(cursor.getColumnIndex("name"));
                        double balance = cursor.getDouble(cursor.getColumnIndex("balance"));
                        Log.e("TAG", "id = " + id + ",name = " + name + ",balance = " + balance);
                    }
                    cursor.close();
                    query_database.close();
                    break;
                case R.id.delete_database: //删除整个数据库
                    DBHelper delete_database_dbHelper = new DBHelper(this, 4);
                    SQLiteDatabase delete_database_database = delete_database_dbHelper.getReadableDatabase();
                    //删除名为user的数据库
                    deleteDatabase("student");
                    break;
            }
        }
    }

    在手机目录中找到相应的student.db数据库所在的位置:/data/data/包名/database/xxx.db

    可以导出来数据库到桌面,下载个SQlite Expert Personal,然后直接拖动就可以查看。

    当然数据库存储的操作远远不止这些,不过实际在项目中我们也经常使用第三方的,比如GreenDao、Litepal等

    五、网络存储

    也就是我们经常使用网络请求框架去请求服务器端的数据,把请求的数据临时存到内存中,需要的时候加载到指定的控件上。

    在这里就不做演示了。这里的网络请求Android系统自带的有HttpUrlConnection、Volley不过现在都用第三方的,Okhhtp、Retrofit在后续的学习当中,我也会好好把这些优秀的框架学习下。

    六、总结

     

     

    展开全文
  • Hive数据的数据存储

    千次阅读 2018-03-07 10:19:23
    Hive建表后,表的元数据存储在关系型数据库中(如:mysql),表的数据(内容)存储在hdfs中,这些数据是以文本的形式存储在hdfs中(关系型数据库是以二进制形式存储的),既然是存储在hdfs上,那么这些数据本身也是...

    Hive建表后,表的元数据存储在关系型数据库中(如:mysql),表的数据(内容)存储在hdfs中,这些数据是以文本的形式存储在hdfs中(关系型数据库是以二进制形式存储的),既然是存储在hdfs上,那么这些数据本身也是有元数据的(在NameNode中),而数据在DataNode中。这里注意两个元数据的不同。
    如下图,建表并导入数据:
    这里写图片描述
    这里写图片描述
    之后在mysql中会发现:
    这里写图片描述
    有一个hive_remote数据库,这里存储的就是hive中表的元数据,比如查看其中一个字段:
    这里写图片描述
    再去查看hdfs中的变化:
    这里写图片描述
    如图,在/user/hive_remote/warehouse/目录下会出现person目录,这就是我们在hive中创建的表,person目录里有一个dt-2018-1-1目录,这个目录里就是我们导入的数据。就是说,这里是按照一个分区一个目录的方式存放的。
    再来看我们在hive中的配置文件hive-site.xml:
    这里写图片描述
    会发现/user/hive_remote/warehouse/这个目录是我们自己配置的路径(hdfs中的路径,不是本地路径)。
    OK,这就是Hive数据的存储方式。

    展开全文
  • Hive的数据压缩与数据存储

    万次阅读 2019-12-12 15:22:01
    二、hive的数据存储格式 列式存储和行式存储 TEXTFILE格式 ORC格式 PARQUET格式 三、存储和压缩结合 一、hive的数据压缩 在实际工作当中,hive当中处理的数据,一般都需要经过压缩,前期我们在学习hadoop的...

    目录

    一、hive的数据压缩

    MR支持的压缩编码

    压缩配置参数

    开启Map输出阶段压缩

    开启Reduce输出阶段压缩

    二、hive的数据存储格式

    列式存储和行式存储

     TEXTFILE格式

    ORC格式

    PARQUET格式

    三、存储和压缩结合


    一、hive的数据压缩

    在实际工作当中,hive当中处理的数据,一般都需要经过压缩,前期我们在学习hadoop的时候,已经配置过hadoop的压缩,我们这里的hive也是一样的可以使用压缩来节省我们的MR处理的网络带宽

    MR支持的压缩编码

    压缩格式

    工具

    算法

    文件扩展名

    是否可切分

    DEFAULT

    DEFAULT

    .deflate

    Gzip

    gzip

    DEFAULT

    .gz

    bzip2

    bzip2

    bzip2

    .bz2

    LZO

    lzop

    LZO

    .lzo

    LZ4

    LZ4

    .lz4

    Snappy

    Snappy

    .snappy

    为了支持多种压缩/解压缩算法,Hadoop引入了编码/解码器,如下表所示

    压缩格式

    对应的编码/解码器

    DEFLATE

    org.apache.hadoop.io.compress.DefaultCodec

    gzip

    org.apache.hadoop.io.compress.GzipCodec

    bzip2

    org.apache.hadoop.io.compress.BZip2Codec

    LZO

    com.hadoop.compression.lzo.LzopCodec

    LZ4

    org.apache.hadoop.io.compress.Lz4Codec

    Snappy

    org.apache.hadoop.io.compress.SnappyCodec

    压缩性能的比较

    压缩算法

    原始文件大小

    压缩文件大小

    压缩速度

    解压速度

    gzip

    8.3GB

    1.8GB

    17.5MB/s

    58MB/s

    bzip2

    8.3GB

    1.1GB

    2.4MB/s

    9.5MB/s

    LZO

    8.3GB

    2.9GB

    49.3MB/s

    74.6MB/s

    在64位模式下的core i7处理器的单核上,Snappy的压缩速度约为250 MB/秒或更高,而解压速度约为500 MB/秒或更高。

     

    压缩配置参数

    要在Hadoop中启用压缩,可以配置如下参数(mapred-site.xml文件中):

    参数

    默认值

    阶段

    建议

    io.compression.codecs  

    (在core-site.xml中配置)

    org.apache.hadoop.io.compress.DefaultCodec, org.apache.hadoop.io.compress.GzipCodec, org.apache.hadoop.io.compress.BZip2Codec,

    org.apache.hadoop.io.compress.Lz4Codec

    输入压缩

    Hadoop使用文件扩展名判断是否支持某种编解码器

    mapreduce.map.output.compress

    false

    mapper输出

    这个参数设为true启用压缩

    mapreduce.map.output.compress.codec

    org.apache.hadoop.io.compress.DefaultCodec

    mapper输出

    使用LZOLZ4snappy编解码器在此阶段压缩数据

    mapreduce.output.fileoutputformat.compress

    false

    reducer输出

    这个参数设为true启用压缩

    mapreduce.output.fileoutputformat.compress.codec

    org.apache.hadoop.io.compress. DefaultCodec

    reducer输出

    使用标准工具或者编解码器,如gzipbzip2

    mapreduce.output.fileoutputformat.compress.type

    RECORD

    reducer输出

    SequenceFile输出使用的压缩类型:NONEBLOCK

     

    开启Map输出阶段压缩

    开启map输出阶段压缩可以减少job中map和Reduce task间数据传输量。具体配置如下:

    案例实操:

    1)开启hive中间传输数据压缩功能

    hive (default)>set hive.exec.compress.intermediate=true;

    2)开启mapreduce中map输出压缩功能

    hive (default)>set mapreduce.map.output.compress=true;

    3)设置mapreduce中map输出数据的压缩方式

    hive (default)>set mapreduce.map.output.compress.codec= org.apache.hadoop.io.compress.SnappyCodec;

    4)执行查询语句

    select count(1) from score;

     

    开启Reduce输出阶段压缩

    当Hive将输出写入到表中时,输出内容同样可以进行压缩。属性hive.exec.compress.output控制着这个功能。用户可能需要保持默认设置文件中的默认值false,这样默认的输出就是非压缩的纯文本文件了。用户可以通过在查询语句或执行脚本中设置这个值为true,来开启输出结果压缩功能。

    案例实操:

    1)开启hive最终输出数据压缩功能

    hive (default)>set hive.exec.compress.output=true;

    2)开启mapreduce最终输出数据压缩

    hive (default)>set mapreduce.output.fileoutputformat.compress=true;

    3)设置mapreduce最终数据输出压缩方式

    hive (default)> set mapreduce.output.fileoutputformat.compress.codec = org.apache.hadoop.io.compress.SnappyCodec;

    4)设置mapreduce最终数据输出压缩为块压缩

    hive(default)>set mapreduce.output.fileoutputformat.compress.type=BLOCK;

    5)测试一下输出结果是否是压缩文件

    insert overwrite local directory '/export/servers/snappy' select * from score distribute by s_id sort by s_id desc;

     

    二、hive的数据存储格式

    Hive支持的存储数据的格式主要有:TEXTFILE(行式存储) SEQUENCEFILE(行式存储)ORC(列式存储)、PARQUET(列式存储)。

     

    列式存储和行式存储

    上图左边为逻辑表,右边第一个为行式存储,第二个为列式存储。

    行存储的特点: 查询满足条件的一整行数据的时候,行存储只需要找到其中一个值,其余的值都在相邻地方。列存储则需要去每个聚集的字段找到对应的每个列的值,所以此时行存储查询的速度更快。

    列存储的特点: 因为每个字段的数据聚集存储,在查询只需要少数几个字段的时候,能大大减少读取的数据量;每个字段的数据类型一定是相同的,列式存储可以针对性的设计更好的设计压缩算法。

    TEXTFILE和SEQUENCEFILE的存储格式都是基于行存储的;

    ORCPARQUET是基于列式存储的。

     

     TEXTFILE格式

    默认格式,数据不做压缩,磁盘开销大,数据解析开销大。可结合Gzip、Bzip2使用(系统自动检查,执行查询时自动解压),但使用这种方式,hive不会对数据进行切分,从而无法对数据进行并行操作。

     

    ORC格式

    Orc (Optimized Row Columnar)是hive 0.11版里引入的新的存储格式。

    可以看到每个Orc文件由1个或多个stripe组成,每个stripe250MB大小,这个Stripe实际相当于RowGroup概念,不过大小由4MB->250MB,这样能提升顺序读的吞吐率。每个Stripe里有三部分组成,分别是Index Data,Row Data,Stripe Footer:

    一个orc文件可以分为若干个Stripe

    一个stripe可以分为三个部分

    indexData:某些列的索引数据

    rowData :真正的数据存储

    StripFooter:stripe的元数据信息

       1)Index Data:一个轻量级的index,默认是每隔1W行做一个索引。这里做的索引只是记录某行的各字段在Row Data中的offset。

       2)Row Data:存的是具体的数据,先取部分行,然后对这些行按列进行存储。对每个列进行了编码,分成多个Stream来存储。

       3)Stripe Footer:存的是各个stripe的元数据信息

    每个文件有一个File Footer,这里面存的是每个Stripe的行数,每个Column的数据类型信息等;每个文件的尾部是一个PostScript,这里面记录了整个文件的压缩类型以及FileFooter的长度信息等。在读取文件时,会seek到文件尾部读PostScript,从里面解析到File Footer长度,再读FileFooter,从里面解析到各个Stripe信息,再读各个Stripe,即从后往前读。

     

    PARQUET格式

    Parquet是面向分析型业务的列式存储格式,由TwitterCloudera合作开发,20155月从Apache的孵化器里毕业成为Apache顶级项目。

    Parquet文件是以二进制方式存储的,所以是不可以直接读取的,文件中包括该文件的数据和元数据,因此Parquet格式文件是自解析的。

    通常情况下,在存储Parquet数据的时候会按照Block大小设置行组的大小,由于一般情况下每一个Mapper任务处理数据的最小单位是一个Block,这样可以把每一个行组由一个Mapper任务处理,增大任务执行并行度。Parquet文件的格式如下图所示。

    上图展示了一个Parquet文件的内容,一个文件中可以存储多个行组,文件的首位都是该文件的Magic Code,用于校验它是否是一个Parquet文件,Footer length记录了文件元数据的大小,通过该值和文件长度可以计算出元数据的偏移量,文件的元数据中包括每一个行组的元数据信息和该文件存储数据的Schema信息。除了文件中每一个行组的元数据,每一页的开始都会存储该页的元数据,在Parquet中,有三种类型的页:数据页、字典页和索引页。数据页用于存储当前行组中该列的值,字典页存储该列值的编码字典,每一个列块中最多包含一个字典页,索引页用来存储当前行组下该列的索引,目前Parquet中还不支持索引页。

     

    三、存储和压缩结合

    官网:https://cwiki.apache.org/confluence/display/Hive/LanguageManual+ORC

    ORC存储方式的压缩:

    Key

    Default

    Notes

    orc.compress

    ZLIB

    high level compression (one of NONE, ZLIB, SNAPPY)

    orc.compress.size

    262,144

    number of bytes in each compression chunk

    orc.stripe.size

    67,108,864

    number of bytes in each stripe

    orc.row.index.stride

    10,000

    number of rows between index entries (must be >= 1000)

    orc.create.index

    true

    whether to create row indexes

    orc.bloom.filter.columns

    ""

    comma separated list of column names for which bloom filter should be created

    orc.bloom.filter.fpp

    0.05

    false positive probability for bloom filter (must >0.0 and <1.0)

    1)创建一个非压缩的的ORC存储方式

    1)建表语句

    create table log_orc_none(

    track_time string,

    url string,

    session_id string,

    referer string,

    ip string,

    end_user_id string,

    city_id string

    )

    ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'

    STORED AS orc tblproperties ("orc.compress"="NONE");

           2)插入数据

    insert into table log_orc_none select * from log_text1 ;

           3)查看插入后数据

    dfs -du -h /user/hive/warehouse/myhive.db/log_orc_none;

    7.7 M  /user/hive/warehouse/log_orc_none/123456_0

    2)创建一个SNAPPY压缩的ORC存储方式

           1)建表语句

    create table log_orc_snappy(

    track_time string,

    url string,

    session_id string,

    referer string,

    ip string,

    end_user_id string,

    city_id string

    )

    ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'

    STORED AS orc tblproperties ("orc.compress"="SNAPPY");

           2)插入数据

    insert into table log_orc_snappy select * from log_text1 ;

           3)查看插入后数据

    dfs -du -h /user/hive/warehouse/myhive.db/log_orc_snappy ;

    3.8 M  /user/hive/warehouse/log_orc_snappy/123456_0

    3)上一节中默认创建的ORC存储方式,导入数据后的大小为

    2.8 M  /user/hive/warehouse/log_orc/123456_0

    Snappy压缩的还小。原因是orc存储文件默认采用ZLIB压缩。比snappy压缩的小。

    4)存储方式和压缩总结:

           在实际的项目开发当中,hive表的数据存储格式一般选择:orcparquet。压缩方式一般选择snappy

     

    展开全文
  • 数据存储方式Android 的数据存储有5种方式:1. SharedPreferences存储数据  SharedPreferences数据存储,也叫作xml存储。这是将数据存储“data/data/程序包名/share_prefs”路径下的到xml文件中。  相关
  • Android中数据存储——文件存储数据

    千次阅读 2015-09-07 21:35:33
    数据存储方式Android 的数据存储有5种方式:1. SharedPreferences存储数据  SharedPreferences数据存储,也叫作xml存储。这是将数据存储“data/data/程序包名/share_prefs”路径下的到xml文件中。 相关
  • 数据存储方式Android 的数据存储有5种方式:1. SharedPreferences存储数据  SharedPreferences数据存储,也叫作xml存储。这是将数据存储“data/data/程序包名/share_prefs”路径下的到xml文件中。 相关连
  • Mysql千万级别数据存储优化

    万次阅读 2020-04-11 12:00:16
    因为公司是做短信业务的,随着数据量的增加每天新增数据将近200w+,数据全部存放至Mongodb中,总数据量将近3.2亿,业务查询相关出现缓慢,于是决定将一周以前的数据存储至Mysql中并对其进行优化处理。 公司内部方案...
  • 数据存储方式Android 的数据存储有5种方式: SharedPreferences存储数据  SharedPreferences数据存储,也叫作xml存储。这是将数据存储“data/data/程序包名/share_prefs”路径下的到xml文件中。 相关连接:
  • PostgreSQL 数据存储结构

    千次阅读 2018-07-16 17:59:23
    PostgreSQL 数据存储结构分为:逻辑储存和物理存储 逻辑存储结构是KingbaseES内部的组织和管理数据的方式。 物理存储结构是操作系统中组织和管理数据的方式。 逻辑存储结构适用于不同的操作系统和硬件平台。 逻辑...
  • Android数据存储

    千次阅读 2016-07-12 13:32:07
    数据存储在Android开发中是很重要的,因为做一个项目一定会用到数据存储,比如游戏或者应用的一些设置配置,游戏存档,应用使用习惯等。这篇主要写本地文件的存储,下篇会介绍数据库相关内容。 这里首先讲Android的...
  • Hadoop数据存储

    万次阅读 2016-05-24 22:49:24
    Hadoop数据存储Hadoop能高效处理数据的基础是有其数据存储模型做支撑,典型的是Hadoop的分布式文件系统HDFS和HBase。一、HDFS文件系统1.0、 HDFS简介HDFS是Hadoop的分布式文件系统的实现,它设计的目的是存储海量的...
  • Hive的数据存储

    千次阅读 2018-07-16 09:35:05
    阅读数:1070Hive的数据分为表数据和元...一、Hive的数据存储在让你真正明白什么是hive 博文中我们提到Hive是基于Hadoop分布式文件系统的,它的数据存储在Hadoop分布式文件系统中。Hive本身是没有专门的数据存储格...
  • Redis 数据存储位置 导出数据

    千次阅读 2017-11-28 12:44:39
    Redis 数据存储位置 导出数据 qq1413139134 2015-12-23 15:25:00 浏览7302 评论0 云数据库Redis版 摘要: Redis是一款支持多种数据类型的Key-Value数据库。这里介绍下如何从Redis中导出数据。 数据是...
  • 360度解析亚马逊AWS数据存储服务

    千人学习 2015-05-19 12:09:35
    在基于云计算进行应用架构设计的时候,数据存储方式与传统企业应用设计有了很大的改变。一方面用户数据存储的需求随着互联网和应用服务的演变有了很大的变化,另一方面随着技术的发展我们现在有了更多的存储服务选择...
  • cocos creator 数据存储

    千次阅读 2018-10-23 18:05:00
    ******数据存储****** cc.sys.localStorage.setItem('存储标识名',变量名);//存储存档数据 var a = cc.sys.localStorage.getItem('存储标识名');//读取存档数据 cc.sys.localStorage.removeItem('存储标识名');//...
  • HDFS数据存储模式

    千次阅读 2019-04-08 16:23:40
    HDFS(Hadoop Distributed File System)是Hadoop分布式计算中的数据存储系统,是基于流数据模式访问和处理超大文件的需求而开发的。下面我们首先介绍HDFS中的一些基础概念,然后介绍HDFS中读写操作的过程,最后分析...
  • MYSQL INNODB数据存储结构

    万次阅读 多人点赞 2018-07-18 17:03:33
    所以先整理InnoDB的数据存储结构。 关键词:Pages, Extents, Segments, and Tablespaces 如何存储表 MySQL 使用 InnoDB 存储表时,会将表的定义和数据索引等信息分开存储,其中前者存储在 .frm 文件中,后者存储...
  • HIVE-元数据存储

    千次阅读 2018-08-22 22:56:48
    HIVE-元数据存储 元数据(Meta Date),主要记录数据仓库中模型的定义、各层级间的映射关 系、监控数据仓库的数据状态及 ETL 的任务运行状态。一般会通过元数据资料库 (Metadata Repository)来统一地存储和...
  • 在Android中一共提供了4种数据存储方式,但是由于存储的这些数据都是其应用程序私有的,所以如果需要在其他应用程序中使用这些数据,就要使用Android提供的Content Provider(数据共享)。 官方文档中有详细的描述...
  • Python数据存储与压缩

    千次阅读 2018-12-10 16:33:14
    Python数据存储与压缩   跑实验要用到数据集,对于一些不大的数据集,为了节省时间,有时候会先预处理,然后将各个文件存储成一个大文件,一次性读入内存,省去了每个迭代重新读入和重新预处理的时间。这里讨论...
  • 数据存储---五种存储方式简介

    万次阅读 2017-04-08 10:22:15
    数据存储方式 1 使用SharedPreferences存储数据; 是Android提供的用来存储一些简单配置信息的一种机制,例如:登录用户的用户名与密码。其采用了Map数据结构来存储数据,以键值的方式存储,可以简单的读取与写入。...
  • 区块链之分布式数据存储

    千次阅读 2018-08-23 17:14:26
    区块链之分布式数据存储 30年前,有一个未来学家提出未来世界的趋势是分布式将代替去中心化:一个机器蜘蛛的六条腿配置分布式的计算引擎,去掉中心化的大脑,结果是这个机器蜘蛛的六条腿之间能够协调自如。 现在的...
  • 数据仓库之-历史数据存储方案

    万次阅读 2017-11-07 21:06:08
    现状:隔一段时间去数据中心获取一次数据,每次获取数据时只有极少部分数据会发生变更,但是系统需要溯源数据变更的情况。方案: 现状表+历史表结合的方式: ... 将全量数据存储在Hbase中,现状数
  • Redis的数据存储形式

    千次阅读 2018-09-07 09:18:34
    redis的数据存储方式 redis 提供持久化功能,把数据以文件的方式持久化到硬盘中,但是目前大多都是redis配合关系数据库使用,持久化仍然由关系数据完成,redis自身的持久化用于保证数据的安全性,以保证存放在redis...
  • 顺序存储在计算机中用一组地址连续的存储单元依次存储线性表的各个数据元素,称作线性表的顺序存储结构。特点:随机存取表中元素。插入和删除操作需要移动元素。链接存储在计算机中用一组任意的存储单元存储线性表的...
  • MySQL修改默认数据存储路径

    千次阅读 2018-07-30 17:04:38
    最近在MySQL数据库里操作了大批量的数据,电脑开始变卡,经查询发现是因为C 盘 被MySQL数据存储文件占用了很多空间,所以,将MySQL默认的数据存储路径进行修改,整理记录如下 1.操作步骤 1.1 停止MySQL服务 ...
  • Zookeeper:运行机制和数据存储机制

    千次阅读 2018-09-21 08:10:52
    zookeeper的基本功能和应用场景 ...zookeeper的数据存储机制 数据存储形式 zookeeper中对用户的数据采用kv形式存储  只是zk有点特别,key是以路径的形式表示的 那就意味着,各key之间有父子关系,比如 / ...
  • Android数据存储五种方式总结

    千次阅读 2019-02-24 16:07:48
    本文介绍Android平台进行数据存储的五大方式,分别如下: 1 使用SharedPreferences存储数据  2 文件存储数据   3 SQLite数据库存储数据  4 使用ContentProvider存储数据  5 网络存储数据 第一种: 使用...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 605,450
精华内容 242,180
关键字:

数据存储