Android学习之网上商城(上)

您所在的位置:网站首页 从学号中提取班级号 Android学习之网上商城(上)

Android学习之网上商城(上)

#Android学习之网上商城(上)| 来源: 网络整理| 查看: 265

前言

到了重新开班的时候,这门课就更难受了,因为两周还有三场考试,开课的时候还要复习,真的很耗费精力,也收获颇丰。接下来,让我们总结一下我们在本课程中所学到的知识。

[En]

When it’s time to set up the class again, this course is more uncomfortable, because there are still three exams in two weeks, and we have to review it when we set it up, which really expends a lot of energy, but also gains a lot. Next, let’s summarize what we have learned in this course.

Android学习之网上商城(上)Android学习之网上商城(下)

源码下载:链接:https://pan.baidu.com/s/1Z17xBHV9iq70LwdgXxwDIQ提取码:Lin2

Android学习之网上商城源代码

本博客内容原创,创作不易,转载请注明

本文链接

个人博客:https://ronglin.fun/?p=118PDF链接:见博客网站CSDN: https://blog.csdn.net/RongLin02/article/details/121876257

开发环境:

Android Studio版本:(Android Studio Arctic Fox 2020.3.1 Patch 3) SDK版本:(Android 7.0 API24 Revision 2) Gradle版本:(7.0.2) Android Gradle Plugin版本:(7.0.3)

选题

题目

本次选题为网上商城/外卖小助手。要求如下:功能要求

对产品展示、商品详细介绍、下单、购物车的要求。 [En]

requirements for product display, detailed introduction of goods, placing orders, shopping carts.*

要求用户注册、登录和查看历时顺序。[En]

users are required to register, log in and view diachronic orders.*

数据:可以采用静态的固定的数据来模拟(如果动手能力较强,可以尝试自己动手搭后台,利用 Android 网络编程)。

目的:

掌握 Android 中的菜单及导航框架。 掌握自定义布局。 掌握 Android 中的数据存储。 分析

1. 商品展示商品展示准备用一个ListView展示内容,主要包括商品的名称、价格、预览图、加入购物车功能等2. 商品详细介绍这个界面准备用一个自定义Dialog实现,主要是布局设计,展示商品的名称、价格、预览图、描述、标签等3. 购物车购物车用一个ListView维护,主要是用来显示用户的购物车内容,这个界面的主要功能就是对购物车中的商品删除和下单扣费,因为是静态数据,准备用ArrayList数组维护4. 下订单暂定实现用户的扣费和将订单加入历史订单中,用ArrayList维护,主要是内容的增加和删除5. 注册用单独的一个Activity实现,主要是用于用户的注册,有三个数据,第一个是用户名,第二个是密码,第三个是确认密码,然后注册成功之后将数据插入本地数据库,用户列表主要用SQLite存储。6. 登录登录是比较用户输入的数据是否与数据库中的数据匹配。如果匹配成功,则登录成功,如果失败,则会提示您。

[En]

Login is to compare whether the data entered by the user matches the data in the database. If the match is made, the login is successful, and if it fails, it prompts you.

7. 历史订单历史订单用SQLite存储,主要记录的是用户的用户名,商品名称和购物时间8. 数据由于时间有限,本次Android设计主要是用静态数据,商品数据由本地写死,用户信息用SQLite数据库维护

效果展示

注册登录

实现账号的注册和登录。注册完成后,登录界面会自动填写注册的账号密码。

[En]

Realize the registration and login of the account. When the registration is completed, the registered account password will be automatically filled in the login interface.

Android学习之网上商城(上) ; 商品展示

商品展示界面,点击各行显示商品详情,点击+号将商品添加到购物车中。

[En]

The display interface of the goods, click on each line to show the details of the goods, and click the + sign to add the goods to the shopping cart.

Android学习之网上商城(上) 购物车

你需要在购物车中扣除手续费,你可以在个人中心充值,然后你可以在购物时扣除手续费。

[En]

You need to deduct the fee in the shopping cart, you can recharge it in the personal center, and then you can deduct the fee when you shop.

Android学习之网上商城(上)

; 用法

这个模块主要用来说明,在本次安卓开发用主要用的部分,一个ListView,一个是viewBinding,一个是Fragment,还有一些其他的用法

ListView

ListView是这其中最常用的控件,包括商品展示,购物车列表展示,个人中心中的历史清单列表,都是用的ListView显示数据。

item

在ListView中,每一行都是一个item,所以说要用ListView首先就是先设计一个item的布局文件,如下图

Android学习之网上商城(上)部分代码如下: ......

这样新建一个item,并且为其中每一个按钮设置好id

BaseAdapter

设计完每一行的显示之后还不行,还要用代码来设计每一个item是如何显示的,这里就用到了Adapter适配器,因为我的数据显示比较复杂,只能用自定义的适配器,定义一个类,继承自 BaseAdapter类,然后实现其中的几个抽象方法,如下

package com.ronglin.linshopping.application; public class GoodsListAdapter extends BaseAdapter{ private ArrayList list_goods; public GoodsListAdapter(ArrayList list, Context context){ this.list_goods = list; this.context = context; } public void setListGoods(ArrayList list){this.list_goods = list;} @Override public int getCount() {return list_goods.size();} @Override public Object getItem(int i) {return list_goods.get(i);} @Override public long getItemId(int i) {return i;} @Override public View getView(int i, View view, ViewGroup viewGroup) { View item_view; item_view = View.inflate(this.context, R.layout.list_item_goods,null); //设置列表的显示形式 TextView textViewGoodsName = item_view.findViewById(R.id.textViewGoodsName); textViewGoodsName.setText(list_goods.get(i).getGoodsName()); return item_view; } }

这个 GoodsListAdapter类就是用来控制每一行如何显示的,为了实现动态数据,用了一个ArrayList实现数据存储,然后显示的数据都从ArrayList中提取这几个方法简单提示一下 getCount()用来获取到底有多少行 getItem(int i)用来获取第i行(从0开始)的数据类 getItemId(int i)用来获取第i行(从0开始)的数据id getView(int i, View view, ViewGroup viewGroup)用来设置第i行(从0开始)的显示形式

Bottom Navigation Activity

因为要实现多个界面切换,在设计时看到Android Studio中的Activity的时候,看到了 Bottom Navigation Activity,是用底边栏按钮切换界面,下面简单介绍一下它的用法

文件分布

bottom_nav_menu.xml首先是 /res/menu下的 bottom_nav_menu.xml,这个文件的作用是控制底边栏的样式,比如购物车的图标,名称之类的,基本格式如下:

文件中主要就是item,根据所查的资料,item的个数是3–5个,icon就是底边栏的按钮图标,title就是底边栏的名称

mobile_navigation.xml然后就是在 /res/navigation下的 mobile_navigation.xml,这个文件就是设置每一个item中面板内容,基本内容如下

android:name 是用来配置控制界面的类,格式是 包名.类名tools:layout 是用来设置每一个界面的布局文件

简单使用

切换界面如果要切换手动切换界面,请使用

[En]

If you want to switch the manual switch interface, use the

binding.imageButtonShopping.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Navigation.findNavController(GoodsFragment.this.getView()).navigate(R.id.navigation_shopping); } });

此代码的目的是切换接口。

[En]

The purpose of this code is to switch the interface.

然后就是Fragment的用法,关于Fragment下面还有用法说明

viewBinding

因为我用的是系统自动生成的 Bottom Navigation Activity(底边栏按钮切换界面),在自动生成的代码中,用到了viewBinding,查了一下资料,发现用起来很方便,这里简单的说一下使用

build.gradle

首先要是想使用viewBinding,要在 build.gradle(Module:xxx)中开启viewBinding

android { compileSdk 30 ...... buildFeatures { viewBinding true } }

然后就可以用了

使用说明

开启viewBinding后,它会把每一个layout目录下的 xml 文件按照 驼峰命名法 生成了一个类,例如 activity_main.xml文件就被生成类 ActivityMainBinding然后就可以通过类的实例来访问其中的控件例如在 test_layout.xml中如下定义

然后在Activity中就可以这样使用

public class MainActivity extends AppCompatActivity { private TestLayoutBinding binding; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); binding = TestLayoutBinding.inflate(getLayoutInflater()); setContentView(binding.getRoot()); binding.editTextSearch.setText("test"); } }

通过binding.Id名称就可以访问到特定的控件了,如果没有在Activity中,只有Context对象的话,可以这样初始化

binding = TestLayoutBinding.inflate(LayoutInflater.from(context));

之后就基本上可以不用 findViewById方法了,就可以直接用binding来访问控件了。注意:当和 ListView中的 BaseAdapter一起使用时,不能用binding,还是要用 findViewById方法,不知道是不是自己用错了,几次尝试之后都显示失败,无果后只能放弃

Fragment

在使用系统自动生成的 Bottom Navigation Activity时,它生成了3个Fragment。以下部分内容来官方API文档Fragment 表示应用界面中可重复使用的一部分。Fragment 定义和管理自己的布局,具有自己的生命周期,并且可以处理自己的输入事件。Fragment 不能独立存在,而是必须由 Activity 或另一个 Fragment 托管。Fragment 的视图层次结构会成为宿主的视图层次结构的一部分,或附加到宿主的视图层次结构。

生命周期

Android学习之网上商城(上)这是它的生命周期图,和Activity很像,简单说明一下,Fragment不能够单独使用,要嵌套在Activity中使用,其生命周期也受到所在Activity的生命周期的影响,需要注意的是,在多个Fragment之中的切换,会调用 onDestroyView和 onCreateView同时数据会清空,但是对应的类并没有被销毁重构,只是界面View被销毁重构 ; ViewModel

在使用 Bottom Navigation Activity的时候,会发现,每一个界面类还会跟随一个 ViewModel类,这个类主要是用来存储数据,用来适配Controller和Model之间的桥梁,同时用ViewModel也可以在多个Fragment中实现数据共享,接下来简单的说明用法

初始化 private GoodsViewModel goodsViewModel; private FragmentGoodsBinding binding; public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { binding = FragmentGoodsBinding.inflate(inflater, container, false); View root = binding.getRoot(); goodsViewModel = new ViewModelProvider(this).get(GoodsViewModel.class); return root; }

可以看到ViewModel的初始化是在 onCreateView中,所以说 每当点击切换Fragment的时候,ViewMode的数据都会重新初始化,这点要尤为注意

设置数据

先来简单的看一下ViewModel类中的变量和方法

public class GoodsViewModel extends ViewModel { private final MutableLiveData goods; public GoodsViewModel() { goods = new MutableLiveData(); } public LiveData getGoods() { return goods; } public void setGoods(Goods goods){ this.goods.setValue(goods); } }

主要的变量就是一个 MutableLiveData类,这个类可以动态监听值的变化,在对应的Fragment类中可以看到以下方法

goodsViewModel.getGoods().observe(getViewLifecycleOwner(), new Observer() { @Override public void onChanged(Goods goods) { Log.i("TAG",Goods.toString()); } });

当类中Goods的值变化的时候就会自动执行 onChanged的代码,参数中的goods是变化之后的值经过我的开发尝试,只有在调用 goodsViewModel.setGoods(goods)的时候才会被监听到,所以说当用 goodsViewModel.getGoods()方法获取到数据之后, 对数据的操作不会引起监听变化,所以说当改变数据之后要调用一下 goodsViewModel.setGoods()方法,如下:

goodsViewModel.getGoods().setPrice(1000); goodsViewModel.setGoods(goodsViewModel.getGoods());

更改此设置后,将调用监视器。

[En]

After this is changed, the monitor will be called.

然后就是在其他的Fragment获取数据

GoodsViewModel goodsViewModel; goodsViewModel = new ViewModelProvider(this).get(GoodsViewModel.class); SQLite

在Android中,数据库是使用SQLite的,关于SQLite用法网上有很多资料,这里简单说一下用法

创建

数据库的创建是需要创建一个类来继承自 SQLiteOpenHelper,然后在类中实现它的抽象方法,如下:

public class MySQLiteHelper extends SQLiteOpenHelper { public MySQLiteHelper(@Nullable Context context) { super(context,"LinShopping.db", null, 1); } @Override public void onCreate(SQLiteDatabase sqLiteDatabase) { sqLiteDatabase.execSQL("create table person(username varchar(30) primary key,password varchar(30))"); } @Override public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) { } }

其中构造函数有很多,我这里只是实现了其中一个,主要是需要一个Context类来初始化,然后还要设置一下数据库的名称,这个数据库的创建是在应用刚安装的时候创建的,只会创建一次,然后在 onCreate方法用来调用 execSQL方法来创建新表

之后有关所有数据库的操作都会用到这个 SQLiteOpenHelper类

操作

我本人习惯将数据库的操纵封装成一个类来调用,所以说新建一个Database类来实现数据库操作

public class Database { private MySQLiteHelper mySQLiteHelper; private SQLiteDatabase database; public Database(MySQLiteHelper mySQLiteHelper){ this.mySQLiteHelper = mySQLiteHelper; } }

因为获取数据库需要用到 SQLiteOpenHelper类,所以在构造函数中就需要传入一个 SQLiteOpenHelper类。同时可以用execSQL方法直接输入SQL语句操作数据,这里不再说明

增加方法比较简单,如下

public void insertPersonToSQLite(Person person){ database = mySQLiteHelper.getWritableDatabase(); ContentValues values = new ContentValues(); values.put("username",person.getUsername()); values.put("password",person.getPassword()); long id = database.insert("person",null,values); database.close(); }

需要定义一个 ContentValues类来保存Key-Value对,然后通过 insert方法插入数据库

删除的用法也比较简单,如下所示:

[En]

The usage of deletion is also relatively simple, as shown below:

public int deletePersonToSQLite(Person person){ database = mySQLiteHelper.getWritableDatabase(); int number = database.delete("person","username =?",new String[]{person.getUsername()}); database.close(); return number; } 改

用法如下

public int updatePersonToSQLite(Person person){ database = mySQLiteHelper.getWritableDatabase(); ContentValues values = new ContentValues(); values.put("password",person.getPassword()); int number = database.update("person",values,"username =?",new String[]{person.getUsername()}); database.close(); return number; } 查

因为查询方法需要返回大量数据,所以使用起来比较麻烦。示例如下:

[En]

Because the query method needs to return a lot of data, it is a little more troublesome to use. The example is as follows:

public ArrayList findPersonFromSQLite(String username){ database = mySQLiteHelper.getReadableDatabase(); ArrayList list = new ArrayList(); Cursor cursor = database.query("person",null,"username=?",new String[]{person.getUsername()},null,null,null); if (cursor.getCount() == 0){ cursor.close(); database.close(); return list; } else { cursor.moveToFirst(); list.add(new Person(cursor.getString(0),cursor.getString(1))); while (cursor.moveToNext()){ list.add(new Person(cursor.getString(0),cursor.getString(1))); } cursor.close(); database.close(); return list; } }

简单来说就是需要一个cursor游标来存储返回的数据,然后通过操作游标来实现数据的获取

其他功能

接下来,有一些常见的小函数,用法。

[En]

Next, there are some common small functions, usage.

监听文本框

有时候我们希望,我们的EditText只能输入特定的内容或者当用户输入完毕后立刻处理结果,这样就需要用到 TextWatcher类了

binding.editTextSearch.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { String search = s.toString().trim(); Log.i("TAG",search); } @Override public void afterTextChanged(Editable editable) { } });

简单的说明一下用法 beforeTextChanged(CharSequence s, int start, int count, int after)s: 修改之前的文字。start: 字符串中即将发生修改的位置。count: 字符串中即将被修改的文字的长度。如果是新增的话则为0。after: 被修改的文字修改之后的长度。如果是删除的话则为0。

onTextChanged(CharSequence s, int start, int before, int count)s: 改变后的字符串start: 有变动的字符串的序号before: 被改变的字符串长度,如果是新增则为0。count: 添加的字符串长度,如果是删除则为0。 afterTextChanged(Editable s)s: 修改后的文字

修改机制如下:文字改变->watcher接收到通知->setText->文字改变->watcher接受到通知->…

参考:Android TextWatcher内容监听死循环可以实现限制用户输入

@Override public void onTextChanged(CharSequence s, int start, int before, int count) { String search = s.toString().trim(); Log.i("TAG",search); editTextSearch.removeTextChangedListener(this); editTextSearch.setText(search); editTextSearch.addTextChangedListener(this); } 定时器

因为Android中的UI界面是一个单线程,所以说如果要实现一个定时器,比如几秒之后干什么,有点小困难,先看实例代码

@SuppressLint("HandlerLeak") Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { //这里写到时间之后的操作 } }; TimerTask task = new TimerTask(){ public void run() { Message message = new Message(); mHandler.sendMessage(message); } }; Timer timer = new Timer(); timer.schedule(task, 1000);

就是需要定义一个 Handler类来处理消息,然后定义一个 TimerTask类来发送消息,用一个 Timer类来启动

显示图片

图片有很多类型,我这里用的是 Bitmap类,从drawable目录下构造 Bitmap的方法如下:

Bitmap bitmap1 = BitmapFactory.decodeResource(context.getResources(), R.drawable.renzituo));

用这个方法在生成release版本的时候,同样会显示,同时操作图片也很方便.

总结

到此,一些本次课设中常用功能实现就总结完毕,接下来就是对单独某些模块的实现总结,未完待续,=w=

Original: https://blog.csdn.net/RongLin02/article/details/121876257Author: 榕林子Title: Android学习之网上商城(上)

相关阅读 Title: 【黄啊码】MySQL入门—2、使用数据定义语言(DDL)操作数据库

大家好!我是黄啊码,上一节的知识点你了解多少了,掌握了多少了,别偷懒哦,今天我们就来掌握一下数据定义语言,说得高级点就是Data Definition Language,简称DDL。

很多同学对DDL的了解都是在于数据库的增、删、改、查,那下边我们就具体来讲讲。

1、创建删除数据库CREATE DATABASE user; // 创建一个名为 user的数据库DROP DATABASE user; // 删除一个名为 user的数据库

2.对数据表进行定义创建表结构的语法是这样的:

CREATE TABLE table_name

比如我们在用户数据库中创建user_info这个表

CREATE TABLE user_info (user_id int(11) NOT NULL AUTO_INCREMENT,user_name varchar(255) NOT NULL);

如上,我们创建了一个叫做user_info的表, 里面有两个字段,一个是 user_id ,它是 int 类型,另一个 user_name 字段是varchar(255)类型。这两个字段都不为空,且 user_id 是递增的,而其中的not null表示非空,切记语句最后要加;【千万要记住】AUTO_INCREMENT代表主键自动增长。有刚入门的同学说什么是主键?>>文章后边我会单纯讲述,别着急。

然而在实际工作中,我们肯定很少写过DDL,这里啊码用Navicat代替,它是一个数据库管理和设计工具,跨平台,支持很多种数据库管理软件,比如 MySQL、Oracle、MariaDB 等,当然你有更好、更符合自己编码的工具也是可以的,不做强制。

【黄啊码】MySQL入门—2、使用数据定义语言(DDL)操作数据库

我们还可对user_name字段进行索引,索引类型为Unique。使用 Navicat 设置如下:

【黄啊码】MySQL入门—2、使用数据定义语言(DDL)操作数据库

相信这时候很多同学又会问我,什么是索引,额,这个如果展开出来会比较长,我们放在后边单独一节课讲就行,啊码只告诉你,索引是把双刃剑,用得好,查得爽,用不好,鱿鱼炒。

[En]

I believe that at this time, many students will ask me, what is an index? er, if this is unfolded, it will be longer. We will just put it in a separate class at the back. Ah, the code only tells you that the index is a double-edged sword. It is good to use, good to check, but not good to use. Squid fried.

3、操作表结构在创建表结构之后,我们还可以对表结构进行修改,虽然直接使用 Navicat进行操作,但对于刚入门的你,有必要了解如何使用 DDL 命令来完成表结构的修改。

1、添加字段,比如我在数据表中添加一个 age 字段,类型为int(11)

ALTER TABLE user_info ADD (age int(11));

2、修改字段名,将 age 字段改成user_age

ALTER TABLE user_info RENAME COLUMN age to user_age

3、修改字段的数据类型,将user_age的数据类型设置为float(3,1)

ALTER TABLE user_age MODIFY user_age float(3,1);

【黄啊码】MySQL入门—2、使用数据定义语言(DDL)操作数据库

我看到不少教程写成这样

ALTER TABLE user_age MODIFY user_age (float(3,1));

然后执行起来就芭比Q了

【黄啊码】MySQL入门—2、使用数据定义语言(DDL)操作数据库

【黄啊码】MySQL入门—2、使用数据定义语言(DDL)操作数据库

4、 删除字段, 删除刚才添加的user_age字段

ALTER TABLE user_info DROP COLUMN user_age;

好了,到这里,我们就开始讲讲上边所说的数据库的常见约束:

主键约束

表中经常有一个列或多列的组合,其值能唯一地标识表中的每一行。这样的一列或多列称为表的主键,通过它可强制表的实体完整性。当创建或更改表时可通过定义 PRIMARY KEY 约束来创建主键。一个表只能有一个 PRIMARY KEY 约束,而且 PRIMARY KEY 约束中的列不能接受空值。由于 PRIMARY KEY 约束确保唯一数据,所以经常用来定义标识列。

作用:

1)保证实体的完整性;

2)加快数据库的操作速度

3)在表中添加新记录时,DBMS会自动检查新记录的主键值,不允许该值与其他记录的主键值重复。

4)DBMS自动按主键值的顺序显示表中的记录。如果没有定义主键,则按输入记录的顺序显示表中的记录。

外键约束

确保了表与表之间引用的完整性。一个表中的外键对应另一张表的主键。外键可以是重复的,也可以为空。比如 user_id 在 user_info 表中是主键,如果你想设置一个成绩表即 user_score,就可以在 user_score 中设置 user_id 为外键,关联到 user_info 表中。

唯一性约束

唯一性约束表明了字段在表中的数值是唯一的,即使我们已经有了主键,还可以对其他字段进行唯一性约束。需要注意的是,唯一性约束和普通索引(NORMAL INDEX)之间是有区别的。唯一性约束相当于创建了一个约束和普通索引,目的是保证字段的正确性,而普通索引只是提升数据检索的速度,并不对字段的唯一性进行约束。

NOT NULL 约束。对字段定义了 NOT NULL,即表明该字段不应为空,必须有取值。

DEFAULT,表明了字段的默认值。如果在插入数据的时候,这个字段没有取值,就设置为默认值。比如我们将user中的身高 height 字段的取值默认设置为 0.00,即DEFAULT 0.00。

CHECK 约束,用来检查特定字段取值范围的有效性,CHECK 约束的结果不能为 FALSE,比如我们可以对身高 height 的数值进行 CHECK 约束,必须≥0,且<300,但在常见的数据库操作中,我们很多时候都会把这类约束放在前后端一起结合验证

数据表设计原则及三范式第一范式(1NF)每一列属性都是不可再分的属性值,确保每一列的原子性合理的根据实际业务数据需求来决定属性,合并相似或相同的列,避免冗余

[En]

Reasonably determine attributes according to actual business data requirements, merge similar or identical columns, and avoid redundancy

比如你弄了一个用户表,但有个列叫做身体部位,可身体部位还能继续分,比如五官之类的。

[En]

For example, you have a user list, but there is a column called body parts, but body parts can continue to be divided, such as facial features and so on.

第二范式(2NF)需要确保数据库表中的每一列都和主键相关,如果是联合主键,则需要和所有主键均相关而不能只与主键和某一部分相关

[En]

You need to make sure that every column in the database table is related to the primary key, and if it is a federated primary key, it needs to be related to all primary keys and not just to the primary key and some part.

在一个数据库表中只能保存一种数据,不可以把多种数据保存在同一张数据库表中

[En]

Only one kind of data can be saved in a database table, and multiple data cannot be saved in the same database table.

这个就好理解了,在我们生活中,我们喜欢分类收纳,就跟垃圾分类一样,你总不能湿垃圾和干垃圾丢在一起吧【我们只说常规操作,不要杠哈】

[En]

This is easy to understand, in our life, we like sorting, just like garbage sorting, you can’t throw wet garbage and dry garbage together. [let’s just talk about routine operation, don’t lever]

第三范式(3NF)确保数据表一个记录中的数据都和主键直接相关,而不是间接相关,不能存在传递关系

[En]

Ensure that the data in a record of the data table is directly related to the primary key, not indirectly, and there can be no transfer relationship.

属性不依赖于其他非主属性假设有个表叫做班级表,学号为主键,它存在 学号 –> 班级编号 –> 班级信息 这么一个主键学号与班级信息的传递关系,不符合第三范式

【解决办法】(1)提取学生表;(2)提取班级表;学生肯定在某一个班级中,所以班级编号可以作为学号(主键)的一个直接关联属性,但班级的其他信息应该放在以班级编号为主键的表中,即可符合第三范式。

遵循范式的优缺点通过以上的了解,可以发现,范式规则有如下特点

结构合理,表含义容易理解及区分冗余较小但性能有所降低,多表查询比单表效率低下总结:数据库表的设计,可以借鉴三大范式的指导办法,同时也需要依赖于实际业务需求,良好的数据库结构不仅可以提高开发人员的开发效率,降低开发难度,还可以提高数据库查询效率,给程序增加可变弹性,当冗余的代价小于查询性能降低的代价时,就应该考虑冗余实现。

[En]

Conclusion: the design of database table can learn from the guiding methods of three paradigms, and at the same time, it also needs to rely on the actual business requirements. A good database structure can not only improve the development efficiency of developers, reduce the difficulty of development, but also improve the efficiency of database query and increase the flexibility of the program. When the cost of redundancy is less than the cost of reduced query performance, redundancy implementation should be considered.

对于职场老鸟,三大范式我们早就滚瓜烂熟了吧,那啊码在这里整理了一套常见使用优化方法:

[En]

For workplace veterans, we are already familiar with the three paradigms, so ah code here collates a set of common usage optimization methods:

数据表应尽量简单可复用。怎么说呢:简单指的是用更少的表、更少的字段、更少的联合主键字段来完成数据表的设计。可复用则是通过主键、外键的使用来增强数据表之间的复用率。因为一个主键可以理解是一张表的代表。键设计得越多,证明它们之间的利用率越高。

[En]

Datasheets should be as simple and reusable as possible. How to put it: simply refers to the design of data tables with fewer tables, fewer fields, and fewer federated primary key fields. Reusable is to enhance the reuse rate between data tables through the use of primary keys and foreign keys. Because a primary key can be understood as a representative of a table. The more keys are designed, the higher the utilization between them.

好了,今天的课程稍微有一丢丢多,大家要好好消化一下,多举一反三,有问题的留个言,别忘了一键三连,下次我们还会再见!

[En]

All right, today’s lesson is a little bit lost, we should digest it well, take more examples, leave a message if you have any problems, don’t forget one button and three in a row, we’ll see you again next time!

我是黄啊码,码字的码,退。。。退。。。退。。。朝!

Original: https://www.cnblogs.com/huangama/p/16506688.htmlAuthor: 黄啊码Title: 【黄啊码】MySQL入门—2、使用数据定义语言(DDL)操作数据库

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/378751/

转载文章受原作者版权保护。转载请注明原作者出处!



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3