当前位置: 代码网 > it编程>数据库>Mysql > MySQL数据库从安装到理解

MySQL数据库从安装到理解

2026年01月05日 Mysql 我要评论
在着手学习任何一门技术时,搭建一个可供实践的环境是至关重要的第一步。这份笔记旨在详尽记录在基于debian/ubuntu的linux系统上,从零开始安装、配置、使用乃至彻底卸载mysql的全过程。在整

在着手学习任何一门技术时,搭建一个可供实践的环境是至关重要的第一步。这份笔记旨在详尽记录在基于debian/ubuntu的linux系统上,从零开始安装、配置、使用乃至彻底卸载mysql的全过程。在整个学习初期,所有操作都将使用root账户来执行。这样做的目的,是为了暂时规避复杂的权限管理问题,使学习者能够将全部精力集中在理解和掌握mysql的核心概念与sql基本语句上。当对基础操作有了扎实的掌握之后,再回过头来学习创建普通用户并进行精细化的权限管理,会是一条更为平滑和高效的学习曲线。

mysql与mariadb:同源而生的数据库系统

在选择开源关系型数据库管理系统(rdbms)时,mysql和mariadb是两个无法绕开的名字。它们之间有着深厚的渊源。mysql最初由mysql ab公司开发,后经sun microsystems,最终被oracle公司收购。由于社区对于mysql在商业公司主导下其开源精神能否延续的担忧,mysql的创始人之一michael “monty” widenius,领导了一个由原mysql开发者组成的核心团队,创建了mariadb。

mariadb是mysql的一个社区驱动的分支,其设计目标是保持与mysql的高度兼容性,使得用户可以轻松地从mysql迁移至mariadb,同时承诺其核心代码将永久保持开源。在功能上,mariadb不仅复刻了mysql的核心功能,还在性能优化、新功能引入(如更多的存储引擎aria、xtradb等)方面有所建树。对于初学者而言,两者的基础sql语法和核心操作几乎完全一致,因此,掌握其中任何一个,都能够为理解另一个打下坚实的基础。

一、mysql的安装与初步配置

本次安装实践是在一个采用apt包管理器的linux发行版(例如ubuntu)上进行的。

1. 更新系统软件包列表

在安装任何新软件之前,一个标准且必要的步骤是同步本地系统的软件包索引。这个操作能够确保系统获取到所有配置的软件源中最新的软件包版本信息、依赖关系以及安全补丁列表。

sudo apt-get update

执行此命令后,终端会开始连接各个软件源服务器,下载最新的包信息。这个过程本身并不会安装或升级系统中的任何软件,它仅仅是刷新了本地的“软件包目录”。

终端执行apt-get update命令后,会显示一系列的gethit条目,分别代表从源服务器下载新的包信息或本地列表已是最新。最后的reading package lists... done表示更新过程顺利完成。

2. 安装mysql服务器

当软件包列表更新至最新状态后,便可以开始安装mysql服务器。

sudo apt-get install mysql-server

这条命令指示apt包管理器下载并安装名为mysql-server的软件包。apt会自动解析其依赖关系,将所有必需的组件,如mysql-client(客户端工具)、mysql-common(通用文件)等一并安装。在现代的linux发行版中,安装脚本通常会自动化完成一系列初始化工作,包括创建数据目录、生成默认配置文件、初始化系统数据库以及启动mysql服务。

执行安装命令后,apt会列出将要安装的新软件包以及它们将占用的磁盘空间,并请求确认。输入y并按下回车键,安装流程就会继续进行。

3. 检查mysql服务状态

安装过程结束后,mysql服务(其后台守护进程名为mysqld)理论上会自动启动。为了验证服务是否正常运行,可以使用service命令或在支持systemd的系统中推荐使用systemctl命令。

sudo service mysql status
# 或者更推荐的方式:
# sudo systemctl status mysql

如果服务成功启动并正在运行,输出信息中会包含active: active (running)的标识。这表明mysql服务器已经在后台就绪,并正在监听网络端口等待客户端的连接。

service mysql status命令的输出结果。其中,绿色的active (running)字样是核心信息,明确指示mysql服务当前处于活动状态。

万一服务未能自动启动,其状态可能会显示为inactive (dead)failed。此时,需要手动启动它:

sudo service mysql start

4. 首次登入mysql

在较新版本的ubuntu或debian系统中,mysql的默认安装配置了一个名为auth_socket(或unix_socket)的认证插件。这个插件的机制是:当一个用户尝试通过本地的unix套接字文件连接mysql时,mysql服务器会向操作系统查询发起连接的进程属于哪个用户。如果操作系统用户是root,并且该用户正在尝试以mysql的root用户身份登录,auth_socket插件就会直接信任操作系统的身份验证,允许其无密码登录。

因此,可以直接通过以下命令进入mysql命令行:

sudo mysql

执行此命令后,如果一切顺利,命令行的提示符会变成mysql>。这标志着已经成功进入mysql的交互式客户端环境,可以开始执行sql语句了。

成功登录mysql后的终端界面。其中包含了欢迎信息、当前mysql服务器的版本号,以及等待用户输入命令的mysql>提示符。

5. 为root用户配置密码

auth_socket插件虽然简化了本地root用户的管理操作,但它也限制了必须通过sudo才能登录,并且无法使用密码从远程客户端(如图形化界面工具或其他服务器)进行连接。为了获得更通用的登录方式,需要将root用户的认证方式改回传统的密码认证。

步骤一:查看当前认证方式

首先,在mysql>提示符下,需要查询root用户当前的认证插件是什么。这可以通过查询mysql系统数据库中的user表来完成。

select user, host, plugin from mysql.user where user = 'root';

这条sql语句的含义是:从名为mysql的数据库里,找到名为user的表,筛选出user字段值为root的所有行,并显示这些行的user(用户名)、host(允许登录的主机地址)和plugin(认证插件)三个字段的内容。

查询结果清晰地显示,对于从localhost连接的root用户,其plugin字段的值是auth_socket,这印证了当前使用的是基于套接字的认证方式。

目标是将这个值修改为mysql_native_password,这是一种使用原生哈希算法存储密码的传统认证方式。

步骤二:修改认证方式并设置密码

使用alter user语句可以修改用户的属性,包括其认证插件和密码。

alter user 'root'@'localhost' identified with 'mysql_native_password' by 'your_password';

对这条语句进行分解:

  • alter user 'root'@'localhost': 明确指出要修改的用户是root,并且此规则仅应用于从localhost(本机)发起的连接。
  • identified with 'mysql_native_password': 将该用户的认证插件更改为mysql_native_password
  • by 'your_password': 为该用户设定一个新的密码。请务必your_password替换为一个强密码。

注意:在原始笔记中,该命令calter user 'root'@'localhost' identified with 'mysql_native_password' you_password';存在两个语法错误:开头的c和密码部分缺少by关键字以及引号。这里已修正为正确的sql语法。

步骤三:刷新权限

mysql为了提升性能,会将用户的权限信息缓存在内存中。当执行了grantrevokealter user等修改权限的操作后,内存中的缓存并不会立即更新。需要显式地执行flush privileges命令,通知mysql服务器从磁盘上的授权表中重新加载权限信息,使刚才的更改立刻生效。

flush privileges;

完成以上步骤后,可以输入exitquit退出mysql客户端。然后,尝试使用新的密码进行登录,以验证配置是否成功:

mysql -u root -p

系统会提示enter password:,输入刚才设置的密码,如果能再次进入mysql>环境,说明密码配置成功。

二、mysql的彻底卸载流程

在某些情况下,例如需要重装一个不同版本的mysql,或者不再需要数据库服务时,就需要进行彻底的卸载,以确保系统中没有残留的配置文件或数据文件干扰后续操作。

  1. 停止mysql服务:在卸载前,必须先停止正在运行的mysqld进程。

    sudo service mysql stop
  2. 卸载核心软件包及配置文件:使用apt-get remove命令并带上--purge选项。remove只删除软件包本身,而--purge会一并删除其全局的配置文件。

    sudo apt-get remove --purge mysql-server mysql-client mysql-common mysql-server-core-* mysql-client-core-*
  3. 移除不再需要的依赖项:在安装mysql时,apt可能自动安装了一些其他的包作为依赖。当mysql被卸载后,这些包如果不再被系统其他软件需要,就成了“孤儿”包。autoremove命令可以安全地清理它们。

    sudo apt-get autoremove
  4. 手动删除数据和日志目录--purge选项主要清理/etc目录下的配置文件,但mysql的数据目录(默认在/var/lib/mysql)和日志文件通常需要手动删除。

    sudo rm -rf /etc/mysql /var/lib/mysql
  5. 清理其他可能的残留文件:为了做到最彻底的清理,可以使用通配符来删除其他可能散落在系统中的相关文件。

    sudo rm -rf /etc/mysql* /var/lib/mysql* /var/log/mysql*
  6. 最后刷新包管理器:完成所有清理工作后,再次更新软件包列表,保持系统包信息的一致性。

    sudo apt-get update

三、重置遗忘的root密码

忘记mysql的root密码是初学者乃至有经验的管理员都可能遇到的问题。mysql提供了一种恢复机制,其核心原理是:以一个临时禁用权限验证系统的特殊模式启动mysql服务,从而允许无密码登录并重置密码,最后再恢复到正常模式。

  1. 停止当前mysql服务:确保任何正常运行的mysqld实例都已关闭。

    sudo systemctl stop mysql
  2. 以安全模式启动mysql:使用mysqld_safe脚本,并附带--skip-grant-tables参数。这个参数是关键,它指示mysql服务器在启动时不加载授权表(grant tables)。因此,服务器不会进行任何权限检查,允许任何用户以任何身份连接,并拥有所有权限。末尾的&符号让该命令在后台执行。

    sudo mysqld_safe --skip-grant-tables &
  3. 无密码登入mysql:由于权限系统被暂时禁用,可以直接以root用户身份连接,无需密码。

    sudo mysql -u root
  4. 执行密码修改操作:进入mysql>环境后,需要按顺序执行以下命令来设置新密码。

    flush privileges;

    这是一个非常重要的步骤。因为服务器启动时跳过了授权表,所以像alter user这样的用户管理命令可能无法正常工作。执行flush privileges会强制服务器将授权表重新加载到内存中,这使得用户管理功能得以恢复。

    alter user 'root'@'localhost' identified by 'yournewstrongpassword!';
    

    现在,可以安全地执行alter user语句来设置新密码。将yournewstrongpassword!替换为一个强度足够的新密码。

    flush privileges;

    再次执行flush privileges,是为了确保新设置的密码被正确地写入磁盘并更新到内存缓存中。

    exit;

    完成操作后,退出mysql客户端。

  5. 停止安全模式下的mysql进程:需要手动结束刚才在后台启动的mysqld进程。使用killall命令可以方便地结束所有名为mysqld的进程。

    sudo killall mysqld
  6. 正常重启mysql服务

    sudo systemctl start mysql
  7. 使用新密码登录验证

    mysql -u root -p

    系统会提示输入密码。输入刚刚设置的新密码,如果能够成功登录,则证明密码重置操作已成功。注意,原始笔记中最后的登录命令为sudo mysql -u root -o-o不是一个标准的mysql客户端参数,应为-p

四、数据库基础核心概念的深化理解

1. 剖析mysql的客户端/服务器架构

mysql是一个遵循经典的客户端/服务器(client/server)模式的软件系统。这个架构是理解其工作方式的基础。

  • mysqld (mysql daemon):这是服务器端的核心。它是一个在操作系统后台持续运行的程序,通常被称为“守护进程”(daemon)。mysqld的主要职责包括:
    • 管理磁盘上的物理数据文件。
    • 监听一个网络端口(默认为tcp 3306),等待客户端的连接请求。
    • 接收并解析客户端发送的sql语句。
    • 执行sql语句,对数据进行增、删、改、查等操作。
    • 管理事务、锁、缓存等。
    • 将执行结果返回给客户端。
    • 所有的数据存储和核心计算都发生在服务器端。
  • mysql:这是官方提供的命令行客户端程序。它的角色是作为用户与mysqld服务器沟通的桥梁。用户在mysql客户端中输入的任何sql命令,都会被打包并通过网络(或本地套接字)发送给mysqld服务器去执行。除了mysql这个命令行工具,任何能够连接到mysql服务器并与之通信的程序,都可被视为客户端,例如图形化管理工具(navicat, dbeaver, mysql workbench)或应用程序中使用的数据库连接库(如java的jdbc驱动)。

这种c/s架构实现了数据与操作的分离,使得数据库的管理和访问变得非常灵活。客户端和服务器可以位于同一台物理机器上,也可以分布在网络的不同节点上,通过网络协议进行通信。

2. 数据库登录命令的详细拆解

登录mysql的命令格式封装了连接服务器所必需的全部信息:

mysql -h [主机地址] -p [端口号] -u [用户名] -p
  • -h (host):指定目标mysql服务器的ip地址或域名。如果省略此参数,客户端会默认尝试连接localhost,即本机。
  • -p (port):指定服务器正在监听的端口号。注意,参数是大写的p。如果省略,默认端口是3306
  • -u (user):指定用于登录的mysql用户名。
  • -p (password):告知客户端,登录需要密码。执行命令后,客户端会交互式地提示输入密码。为了安全,密码输入时不会在屏幕上显示。也可以将密码直接跟在-p后面(如-pyourpassword),但这会将密码暴露在命令行历史记录中,存在安全风险,因此不推荐在生产环境中使用。

这是一个尝试使用root用户连接到ip地址为12.0.0.1、端口为3306的mysql服务器的命令。

当只使用mysql -u root -p时,由于省略了-h-p参数,客户端会使用默认值,尝试连接localhost3306端口。

3. 数据库的本质与主流产品概览

  • 数据库的定义:从广义上讲,数据库(database, db)是一个有组织的数据集合。但在计算机科学中,这个词通常指代数据库管理系统(dbms)。mysql就是一种关系型数据库管理系统(rdbms)。dbms不仅是存储数据的文件集合,它更是一套复杂的软件系统,提供了用于定义数据结构(data definition)、操纵数据(data manipulation)、控制数据访问(data control)、保证数据一致性和持久性(transaction control)以及高效检索数据的一整套解决方案。
  • 主流数据库产品巡礼
    • oracle:甲骨文公司的商业数据库产品,功能极为强大和完善,长期以来是大型企业、金融、电信等关键业务领域的首选。它以其稳定性、安全性和对复杂事务处理的强大支持而闻名,但其许可费用和维护成本也相对高昂。
    • sql server:微软公司的关系型数据库产品,与windows server操作系统和.net开发框架深度集成,为开发者提供了无缝的体验。在中大型企业应用,特别是基于微软技术栈的项目中非常流行。
    • mysql:作为全球最受欢迎的开源关系型数据库,mysql以其高性能、高可靠性和易用性在web开发领域占据了主导地位。它是lamp(linux, apache, mysql, php/python/perl)和lnmp(linux, nginx, mysql, php/python/perl)等经典web架构的核心组件。
    • postgresql:被誉为“功能最先进的开源关系型数据库”。它在遵循sql标准、数据类型支持(如json、gis)、可扩展性和处理复杂查询方面表现出色,近年来在需要高级功能和严格数据一致性的应用中越来越受欢迎。
    • sqlite:一个非常轻量级的、无服务器的、嵌入式数据库引擎。它的整个数据库就是一个单一的磁盘文件,作为一个c语言库被直接集成到应用程序中。因其零配置、事务性强的特点,广泛应用于移动设备(android和ios内置)、桌面软件和物联网设备中。
    • h2:一个用java编写的开源嵌入式数据库,可以方便地嵌入到任何java应用程序中。它支持标准的sql,并提供内存数据库模式,非常适合用于单元测试、快速原型开发和小型应用。

4. windows环境下的服务器管理

对于在windows环境下安装的mysql,可以通过图形化的服务管理器进行启停操作。按下win + r键打开“运行”对话框,输入services.msc并回车,即可打开服务列表。

windows的服务管理器界面,在列表中找到名为“mysql”的服务(版本号可能不同),可以方便地对其进行启动、停止、暂停、重启动等操作。

5. 服务器、数据库、表的物理关系

在linux文件系统上,mysql的逻辑结构与物理存储之间存在着清晰的对应关系,理解这一点有助于形成一个直观的认知:

  • mysql服务器 (mysqld):对应一个正在运行的进程,它管理着一个指定的数据目录(data directory)。
  • 数据库 (database):在逻辑上是表的集合。在物理上,每个数据库通常对应数据目录下的一个子目录。例如,执行create database school;后,在mysql的数据目录(如/var/lib/mysql/)下会创建一个名为school的文件夹。
  • 表 (table):在逻辑上是数据的二维结构。在物理上,每张表对应其所属数据库目录下的一个或多个文件。这些文件的具体格式和数量由该表所使用的存储引擎决定。例如,对于默认的innodb存储引擎,一张名为students的表通常会生成students.frm(存储表结构定义)和students.ibd(存储表的数据和索引)两个文件。

这个层级关系图形象地表达了:一个mysql服务器实例可以管理多个数据库,而每个数据库又可以包含多张数据表。

6. 一个完整的数据库操作实例

下面通过一个从创建数据库到查询数据的完整流程,来演示sql的基本用法。

创建数据库

create database helloworld;

这条命令指示mysql服务器创建一个名为helloworld的数据库。

选择要操作的数据库

use helloworld;

在进行表操作之前,必须先通过use命令告诉mysql当前会话的上下文是哪个数据库。后续所有不显式指定数据库的sql语句都将在helloworld数据库中执行。

执行use helloworld;命令后,mysql返回database changed,确认当前工作数据库已切换。

创建数据表

create table student (
    id int,
    name varchar(32),
    gender varchar(2)
);

向表中插入数据

insert into student (id, name, gender) values (1, '张三', '男');
insert into student (id, name, gender) values (2, '李四', '女');

使用两条insert into语句,向student表中添加了两行记录。

从表中查询数据

select * from student;

select *是一个dql(数据查询语言)语句,*代表查询所有列,from student指定了查询的数据源是student表。

查询命令的执行结果以一个清晰的表格形式返回,包含了student表中当前存储的所有行和列的数据。

五、mysql 逻辑架构的深入剖析

mysql之所以能够高效、稳定地工作,得益于其精心设计的分层式、插件化的架构。这种架构使得各个组件职责分明,易于维护和扩展。

这是一个经典的mysql逻辑架构图,它将mysql自顶向下划分为三个主要层次:连接层、核心服务层和存储引擎层。

第一层:连接层 (connectors & connection pool)
这是最外层,直接与客户端打交道。它负责处理所有与连接相关的任务:

  • 连接处理与线程管理:接收来自各种客户端(connectors)的连接请求。mysql采用“一个连接一个线程”的模型,为每个客户端连接分配一个专用的服务线程。
  • 连接池:管理和复用数据库连接,避免了为每个请求都重复进行tcp握手和mysql认证的昂贵开销,这对于需要处理大量短连接的应用至关重要。
  • 身份认证:验证客户端提供的用户名和密码是否正确。
  • 权限验证:在用户成功登录后,其后续的每一个操作都会经过权限检查,确保用户只执行其被授权的操作。

第二层:核心服务层 (sql interface, parser, optimizer, caches & buffers)
这一层是mysql的大脑,负责所有核心的数据处理逻辑。它接收来自连接层的sql请求,并最终将执行指令传递给存储引擎层。

  • sql接口 (sql interface):接收sql命令,并返回查询结果。
  • 解析器 (parser):对sql语句进行词法分析和语法分析,生成一个内部数据结构,通常是“解析树”。如果sql语句存在语法错误,解析阶段就会被驳回。
  • 优化器 (optimizer):这是决定查询性能的核心组件。优化器会分析解析树,并根据mysql内部的统计数据(如表的行数、索引的基数等),生成多个可能的执行计划。然后,它会使用一个基于成本的模型来评估这些计划,并选择一个它认为执行成本最低的计划。例如,它会决定是使用全表扫描还是使用索引,以及在多表连接时应该采用什么样的连接顺序。
  • 缓存与缓冲区 (caches & buffers):包括多个重要的内存区域,如innodb的缓冲池(buffer pool),用于缓存数据页和索引页,以减少磁盘i/o。在mysql 8.0之前还有一个查询缓存(query cache),用于缓存select查询的完整结果集,但由于其在写密集型负载下维护成本高昂且易失效,现已被移除。

第三层:存储引擎层 (storage engines)
这是mysql架构中最具特色的部分,负责数据的物理存储和检索。mysql的设计允许用户为数据库中的每一张表选择不同的存储引擎,这种“可插拔”的机制赋予了mysql极大的灵活性。

  • 存储引擎是真正与底层文件系统交互的组件。它定义了数据在磁盘上的存储格式、索引的实现方式、锁的粒度等。
  • 核心服务层通过一个标准的api与存储引擎层通信,它不关心数据是如何被存储的,只关心如何调用api来存取数据。

1. sql语言的逻辑分类

结构化查询语言(sql)根据其功能,通常被划分为以下几个主要类别:

  • ddl (data definition language):数据定义语言。用于创建、修改和删除数据库中的各种对象,如数据库本身、表、视图、索引等。
    • 核心指令:create, alter, drop, truncate
  • dml (data manipulation language):数据操纵语言。用于对表中的数据进行操作。
    • 核心指令:insert, update, delete
    • dql (data query language):数据查询语言。由于select语句的使用频率和复杂性远超其他dml操作,它常被单独划分为一类。
  • dcl (data control language):数据控制语言。用于定义用户的访问权限和安全级别。
    • 核心指令:grant (授权), revoke (撤销权限)。
  • tcl (transaction control language):事务控制语言。用于管理数据库事务,确保数据操作的原子性、一致性、隔离性和持久性(acid)。
    • 核心指令:commit (提交事务), rollback (回滚事务), savepoint (设置事务保存点)。

2. 存储引擎深入探讨

可以通过执行show engines;命令来查看当前mysql实例支持的所有存储引擎及其特性。

show engines;

show engines;命令的输出结果。这个表格列出了所有可用的存储引擎,其中engine列是名称,support列表示是否可用,default表示该引擎是当前服务器的默认存储引擎。transactionsxa列指明了其事务支持能力。

在众多存储引擎中,innodbmyisam是最为著名和常用的两种。

这个对比图直观地总结了innodb和myisam在几个关键维度上的核心差异。

innodb

  • 当前默认引擎:自mysql 5.5版本起,innodb就成为了默认的存储引擎。
  • 事务安全:完全支持acid兼容的事务,提供了提交(commit)、回滚(rollback)和崩溃恢复能力,是需要保证数据强一致性应用的首选。
  • 行级锁定:在执行写操作时,innodb只锁定需要修改的行,而不是整张表。这极大地减少了锁冲突,显著提高了在高并发写入场景下的性能。
  • 外键约束:支持外键,可以用来强制实施表与表之间的引用完整性,从数据库层面保证数据的关联正确性。
  • 适用场景:绝大多数需要事务支持、高并发读写、数据完整性要求高的应用,例如在线交易系统(oltp)、金融服务、电子商务后台等。

myisam

  • 历史默认引擎:在mysql 5.5版本之前是默认存储引擎。
  • 无事务支持:不支持事务。这意味着它的操作是“非事务性”的,如果一个操作包含多个步骤而中途失败,无法自动回滚到初始状态。
  • 表级锁定:其锁定机制非常简单,任何写操作(insert, update, delete)都会锁定整张表。当一个会话在写表时,其他所有会话的写操作都必须等待,这在写操作频繁时会成为严重的性能瓶颈。
  • 读取性能:由于其结构和锁定机制相对简单,开销较小,在纯粹的只读或读远多于写的场景下,其查询性能有时会略优于innodb。
  • 全文索引:曾是myisam的一个主要优势,但现在innodb也提供了强大的全文索引功能。
  • 适用场景:读密集型、对事务完整性要求不高的应用,例如一些日志记录表、数据仓库的某些事实表或内容管理系统的文章表。

在今天的应用开发中,鉴于innodb在功能、性能和可靠性上的全面优势,除非有非常明确和特殊的理由,否则都应该选择并使用innodb作为存储引擎

最终总结

mysql作为一个构建在操作系统之上的复杂软件系统,其分层架构是其高效、灵活和可扩展性的基石。连接层作为门户,负责处理客户端的接入和安全;核心服务层作为大脑,对sql进行智能的解析、优化和调度;而可插拔的存储引擎层则作为执行者,提供了多样化的物理存储方案以应对不同的业务需求。从网络模型的角度来看,这三层协同工作,共同构成了应用层的数据库服务。最终,由存储引擎与操作系统内核进行交互,将数据安全、持久地写入磁盘。通过本次从安装、配置到深入其架构和核心概念的完整学习过程,为后续进行更复杂的数据库设计、sql优化和管理维护工作奠定了坚实的基础。

到此这篇关于mysql数据库从安装到理解的文章就介绍到这了,更多相关mysql数据库安装内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2026  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com