铜螺母,铜螺丝,螺栓,螺钉工厂网站建设
废气处理设备,如活性炭吸附箱、RTO蓄热式氧化处理设备、光氧等离子复合设备 低温等离子设备 光氧催化设备等网企业网站建设
工业纸箱 纸箱 包装彩印 纸托盘 纸护角公司网站建设
办公区绿植租赁公司网站建设 定制苗圃直供企业网站
使用 Sphinx 索引内容、快速查找文本并提供有用的搜索结果
此文出处:天津网站建设-----天津虎网科技(www.huwz.com)技术总监博客
虽然 Google 及其系列产品几乎无所不能,但是 Web 形式的强大搜索引擎并不能很好地适用于每个站点。如果站点内容已被高度专注化或已明确分类,那就需要使用 Sphinx 和 PHP 来创建一个优化的本地搜索系统。
在 Internet 时代,人们希望信息能够像快餐一样被打包起来:能够快速无障碍使用,并且分为很小的单位(或者是以字节 大小为单位?)。实际上,为了满足急躁而又渴求信息的用户的需求,甚至最普通的 Web 站点现在都要求具有快速浏览样式的各种菜单:
幸运的是,PHP 开发人员可以找到各种 RSS、blog 和论坛软件来创建或者改进站点。而且,虽然 Google 和其他搜索站点几乎无所不能并且执行过滤通信,但是搜索引擎并不一定会良好地适应各个站点。
例如,如果 Web 站点提供成百上千的全新和翻新的保时捷汽车零件,Google 可能通过诸如 “Carrera parts” 之类的广义搜索找到您的站点,但是对于更具体的 “used 1991 Porsche 911 Targa headlight bezel” 查询,它可能不会得到精确结果。
如果站点内容高度专注化,或者访问者期望搜索功能与现实工作流类似,那么较好在 Web 的全局搜索引擎基础上增加一个为您的站点量身定做的本地搜索系统(有关专注化搜索的更多实例,请参阅 “A needle in a billion haystacks”)。
通过本文了解如何向 PHP 站点中添加一个快速、高效、开源和免费的搜索引擎。本文没有开发可见的 Web 站点。相反,重点讨论交付有效搜索结果所需的组件:数据库、索引、搜索引擎和 PHP 应用程序编程接口 (API)。
要为站点提供自定义搜索功能,您必须有数据源和搜索该数据源的功能。对于 Web 应用程序,数据源通常是一个关系数据库,其中内置了一些搜索功能(Equality 是一个简单的搜索运算符,与 SQL 运算符 LIKE 一样)。但是,一些搜索可能比数据库可以执行的搜索更加具体,或者搜索可能过于复杂,而导致固有的 SQL JOIN 反应迟钝。
许多站点提供特定于某一个行业、职业或者娱乐的内容,例如医药、法律、音乐和汽车维修。深入研究这些内容可能要求使用特殊工具或者培训,或者仅需要使用一个索引来生成相关的实用结果。
下面是一些需要定制搜索系统的常见搜索场景:
要加速搜索,您可以重新安排表,并由此简化底层查询(表和 SQL 查询优化高度依赖于模式和引擎。可通过在线搜索查找有关数据库性能的各种文章和书籍)。此外,您可以添加一个专门化的搜索引擎。应用哪种形式的搜索引擎还依赖于数据的形式(和数量)和预算。有许多选择可用:您可以将一个 Google 工具连接到您的网络中,购买 Endeca 或其他大型商业搜索产品,或者尝试 Lucene。但是在很多情况下,使用商业产品都有点小题大做,或者浪费运营预算,并且 Lucene 在 2007 年 7 月编写时并未提供 PHP API。
作为一个备选方案,考虑一下 Sphinx,它是一种开源和免费的搜索引擎,可以非常快速地搜索文本。例如,在一个几乎有 300,000 行及五个索引列(每列包含大约 15 个单词)的活动数据库中,Sphinx 可以在 1/100 秒内得到 “这些单词中任何一个单词” 的搜索结果(在运行 Debian Linux® Sarge 的 2-GHz AMD Opteron 处理器、1 GB RAM 的计算机上)。
Sphinx 提供了大量功能,包括:
您可以在 Sphinx 源代码附带的 README 文件中或通过在线资料找到完整的功能列表。Sphinx Web 站点还列出了已经部署了 Sphinx 的若干个项目。
Sphinx 是用 C++ 编写、用 GNU 编译器构建、支持 64 位支持平台,并在 Linux、UNIX®、Microsoft® Windows® 和 Mac OS X 上运行。构建 Sphinx 十分简单:下载并解压缩代码,然后运行 ./configure && make && make install 命令。
默认情况下,Sphinx 实用程序将被安装到 /usr/local/bin/ 中,并且所有 Sphinx 组件的配置文件都位于 /usr/local/etc/sphinx.conf 中。
Sphinx 有三个组件:索引生成器、搜索引擎和命令行 search 实用程序:
此外,Sphinx 的作者 Andrew Aksyonoff 和其他贡献者为 PHP、Perl、C/C++ 和其他编程语言提供了 API。
回页首
假定 Body-Parts.com 出售车身零件 —— 挡泥板、铬、缓冲器等 —— 用于珍贵且值得收藏的汽车。正如在现实世界中,Body Parts 站点的访问者很可能按制造商(比如保时捷或制造同类零件的第三方制造商)、零件号、产地、车型、年份、条件(二手、全新、翻新)以及描述或者这些属性的某种组合来搜索零件。
要构建 Body Parts 搜索功能,让我们使用 MySQL V5.0 作为数据存储并使用 Sphinx search 守护程序来提供快速而精确的文本搜索。MySQL V5.0 是一个功能强大的数据库,但是它的增强型全文本搜索功能并不特别丰富。实际上,它仅限于 MyISAM 表 —— 不支持外键的一种表格式,因此使用有限。
清单 1 至清单 4 显示了与此示例相关的 Body Parts 模式的部分代码。您将分别看到 Model(清单 1)、Assembly(清单 2)、Inventory(清单 3)和 Schematic(清单 4)表。
清单 1 中所示的 Model 表十分简单:label 列将列举车型的名称 (“Corvette”);description 使用客户友好方式进行描述(“两门跑车;⑴年引入”);而 begin_production 和 end_production 分别表示开始生产和结束生产该车型的年份。由于前述列中的值并不惟一,因此使用一个独立 ID 表示每四个这样的元素(label、description、begin_production、end_production),并且是其他表中的外键。
CREATE TABLE Model ( id int(10) unsigned NOT NULL auto_increment, label varchar(7) NOT NULL, description varchar(256) NOT NULL, begin_production int(4) NOT NULL, end_production int(4) NOT NULL, PRIMARY KEY (id) ) ENGINE=InnoDB;
下面是 Model 表的一些样例数据:
INSERT INTO Model (`id`, `label`, `description`, `begin_production`, `end_production`) VALUES (1,'X Sedan','Four-door performance sedan',1998,1999), (3,'X Sedan','Four door performance sedan, 1st model year',1995,1997), (4,'J Convertible','Two-door roadster, metal retracting roof',2002,2005), (5,'J Convertible','Two-door roadster',2000,2001), (7,'W Wagon','Four-door, all-wheel drive sport station wagon',2007,0);
assembly 是一个子系统,例如汽车上安装的传动装置或所有玻璃。车主使用部件图及相关零件列表来查找备件。清单 2 中所示的 Assembly 表也十分简单:它将把一个惟一 ID 与部件标签和描述关联起来。
CREATE TABLE Assembly ( id int(10) unsigned NOT NULL auto_increment, label varchar(7) NOT NULL, description varchar(128) NOT NULL, PRIMARY KEY (id) ) ENGINE=InnoDB;
继续示例,下面是 Assembly 表的一些样例数据:
INSERT INTO Assembly (`id`, `label`, `description`) VALUES (1,'5-00','Seats'), (2,'4-00','Electrical'), (3,'3-00','Glasses'), (4,'2-00','Frame'), (5,'1-00','Engine'), (7,'101-00','Accessories');
Inventory 表是汽车零件的典范列表。零件 —— 例如螺钉或灯泡 —— 可能用于每辆汽车和多个部件中,但是零件只在 Inventory 表中显示一次。Inventory 表中的每行包含:
Inventory 表的规范如清单 3 中所示:
CREATE TABLE Inventory ( id int(10) unsigned NOT NULL auto_increment, partno varchar(32) NOT NULL, description varchar(256) NOT NULL, price float unsigned NOT NULL default '0', PRIMARY KEY (id), UNIQUE KEY partno USING BTREE (partno) ) ENGINE=InnoDB;
零件的(部分)列表可能如下面所示:
INSERT INTO `Inventory` (`id`, `partno`, `description`, `price`) VALUES (1,'WIN408','Portal window',423), (2,'ACC711','Jack kit',110), (3,'ACC43','Rear-view mirror',55), (4,'ACC5409','Cigarette lighter',20), (5,'WIN958','Windshield, front',500), (6,'765432','Bolt',0.1), (7,'ENG001','Entire engine',10000), (8,'ENG088','Cylinder head',55), (9,'ENG976','Large cylinder head',65);
Schematic 表将把零件与部件和车型版本绑定在一起。因此,将使用 Schematic 表来查找组装 1979 J Class 敞篷车引擎的所有零件。Schematic 表中的每行都有一个惟一 ID,一个引用 Inventory 表行的外键,一个标识部件的外键,以及用于引用 Model 表中特定型号和版本的另一个键。各行如清单 4 所示:
CREATE TABLE Schematic ( id int(10) unsigned NOT NULL auto_increment, partno_id int(10) unsigned NOT NULL, assembly_id int(10) unsigned NOT NULL, model_id int(10) unsigned NOT NULL, PRIMARY KEY (id), KEY partno_index USING BTREE (partno_id), KEY assembly_index USING BTREE (assembly_id), KEY model_index USING BTREE (model_id), FOREIGN KEY (partno_id) REFERENCES Inventory(id), FOREIGN KEY (assembly_id) REFERENCES Assembly(id), FOREIGN KEY (model_id) REFERENCES Model(id) ) ENGINE=InnoDB;
为了强化表的意图,下面是 Schematic 中的一张小型行列表:
INSERT INTO `Schematic` (`id`, `partno_id`, `assembly_id`, `model_id`) VALUES (1,6,5,1), (2,8,5,1), (3,1,3,1), (4,5,3,1), (5,8,5,7), (6,6,5,7), (7,4,7,3), (8,9,5,3);
定义了这些表后,就可以轻松地响应很多搜索:
但是很多搜索代价较大:
这些搜索中的每个搜索都要求使用长篇的 JOIN 子句或代价高昂的 LIKE 子句,尤其是在 Inventory 表和 Schematic 表十分大时更是如此。而且,复杂的文本搜索完全超出了 MySQL 的能力。要搜索大量文本数据,请考虑构建和使用 Sphinx 索引。
回页首
要应用 Sphinx 来解决问题,您必须定义一个或多个数据源以及一个或多个索引。
source 将标识数据库来建立索引,提供验证信息,并且定义查询用以构造每行。数据源可以随意地标识一列或多列作为过滤器,Sphinx 将之称为组。您将使用组来过滤结果。例如,单词描述可能得到 900 个匹配。如果只对特定型号的汽车匹配感兴趣,则可以进一步使用型号组进行过滤。
index 将要求获得数据源(即一组数据行)并定义应当如何为已从数据源中提取出来的数据编目。
您将在 sphinx.conf 文件中定义数据源和索引。Body Parts 的数据源是 MySQL 数据库。清单 5 显示了名为 catalog 的数据源的部分定义 —— 指定连接的数据库以及如何建立连接(主机、套接字、用户和密码)的代码片段。
source catalog { type = mysql sql_host = localhost sql_user = reaper sql_pass = s3cr3t sql_db = body_parts sql_sock = /var/run/mysqld/mysqld.sock sql_port = 3306
接下来,创建一个查询以生成要被索引的行。通常,将创建 SELECT 子句,可能需要把许多表 JOIN 在一起才能得到行。但这里存在一个问题:搜索型号和年份必须使用 Assembly 表,但是零件号和零件描述只能在 Inventory 表中找到。为此,Sphinx 必须能够把搜索结果与 32 位整型主键绑定在一起。
要获得右侧表单中的数据,需要创建一个视图 —— MySQL V5 中的新结构,它将把来自其他表的列整合到单独的合成虚拟表中。使用视图,各类搜索所需的所有数据都在一个位置,但是活动数据实际上存在于其他表中。清单 6 显示了定义 Catalog 视图的 SQL。
CREATE OR REPLACE VIEW Catalog AS SELECT Inventory.id, Inventory.partno, Inventory.description, Assembly.id AS assembly, Model.id AS model FROM Assembly, Inventory, Model, Schematic WHERE Schematic.partno_id=Inventory.id AND Schematic.model_id=Model.id AND Schematic.assembly_id=Assembly.id;
如果用前面所示的表和数据创建名为 body_parts 的数据库,则 Catalog 视图应当类似以下内容:
mysql> use body_parts; Database changed mysql> select * from Catalog; +----+---------+---------------------+----------+-------+ | id | partno | description | assembly | model | +----+---------+---------------------+----------+-------+ | 6 | 765432 | Bolt | 5 | 1 | | 8 | ENG088 | Cylinder head | 5 | 1 | | 1 | WIN408 | Portal window | 3 | 1 | | 5 | WIN958 | Windshield, front | 3 | 1 | | 4 | ACC5409 | Cigarette lighter | 7 | 3 | | 9 | ENG976 | Large cylinder head | 5 | 3 | | 8 | ENG088 | Cylinder head | 5 | 7 | | 6 | 765432 | Bolt | 5 | 7 | +----+---------+---------------------+----------+-------+ 8 rows in set (0.00 sec)
在视图中,字段 id 将指回 Inventory 表中的零件条目。partno 和 description 列是要搜索的主要文本,而 assembly 和 model 列用作进一步过滤结果的组。视图就绪后,构造数据源查询就是小事一桩。清单 7 显示了 catalog 数据源定义的其余部分。
# indexer query # document_id MUST be the very first field # document_id MUST be positive (non-zero, non-negative) # document_id MUST fit into 32 bits # document_id MUST be unique sql_query = \ SELECT \ id, partno, description, \ assembly, model \ FROM \ Catalog; sql_group_column = assembly sql_group_column = model # document info query # ONLY used by search utility to display document information # MUST be able to fetch document info by its id, therefore # MUST contain '$id' macro # sql_query_info = SELECT * FROM Inventory WHERE id=$id }
sql_query 必须包括后续查找需要使用的主键,并且它必须包括需要索引和用作组的所有字段。两个 sql_group_column 条目将声明 Assembly 和 Model 可用于过滤结果。并且 search 实用程序将使用 sql_query_info 来查找匹配记录。在查询中,$id 被替换为 searchd 返回的每个主键。
最后一个配置步骤是构建索引。清单 8 显示了数据源 catalog 的索引。
index catalog { source = catalog path = /var/data/sphinx/catalog morphology = stem_en min_word_len = 3 min_prefix_len = 0 min_infix_len = 3 }
第 1 行将指向 sphinx.conf 文件中的指定数据源。第 2 行将定义存储索引数据的位置;按照约定,Sphinx 索引将被存储到 /var/data/sphinx 中。第 3 行将允许索引使用英文词法。并且第 5 行至第 7 行将告诉索引器只索引含有三个字符或更多字符的那些单词,并且为每个这样的字符的子字符串创建中缀索引(为了便于引用,清单 9 显示了 Body Parts 的完整示例 sphinx.conf 文件)。
source catalog { type = mysql sql_host = localhost sql_user = reaper sql_pass = s3cr3t sql_db = body_parts sql_sock = /var/run/mysqld/mysqld.sock sql_port = 3306 # indexer query # document_id MUST be the very first field # document_id MUST be positive (non-zero, non-negative) # document_id MUST fit into 32 bits # document_id MUST be unique sql_query = \ SELECT \ id, partno, description, \ assembly, model \ FROM \ Catalog; sql_group_column = assembly sql_group_column = model # document info query # ONLY used by search utility to display document information # MUST be able to fetch document info by its id, therefore # MUST contain '$id' macro # sql_query_info = SELECT * FROM Inventory WHERE id=$id } index catalog { source = catalog path = /var/data/sphinx/catalog morphology = stem_en min_word_len = 3 min_prefix_len = 0 min_infix_len = 3 } searchd { port = 3312 log = /var/log/searchd/searchd.log query_log = /var/log/searchd/query.log pid_file = /var/log/searchd/searchd.pid }
底部的 searchd 部分将配置 searchd 守护程序本身。该部分中的条目不言自明。query.log 尤为有用:它将在运行时显示每次搜索并显示结果,例如搜索的文档数和匹配总数。
回页首
您现在已经准备好为 Body Parts 应用程序构建索引。为此,需要执行以下步骤:
contentnbsp;sudo /usr/local/bin/indexer --config /usr/local/etc/sphinx.conf --all Sphinx 0.9.7 Copyright (c) 2001-2007, Andrew Aksyonoff using config file '/usr/local/etc/sphinx.conf'... indexing index 'catalog'... collected 8 docs, 0.0 MB sorted 0.0 Mhits, 82.8% done total 8 docs, 149 bytes total 0.010 sec, 14900.00 bytes/sec, 800.00 docs/sec
注:-all 参数将重构 sphinx.conf 中列出的所有索引。如果不需要重构所有索引,您可以使用其他参数只对部分索引进行重构。contentnbsp;/usr/local/bin/search --config /usr/local/etc/sphinx.conf ENG Sphinx 0.9.7 Copyright (c) 2001-2007, Andrew Aksyonoff index 'catalog': query 'ENG ': returned 2 matches of 2 total in 0.000 sec displaying matches: 1. document=8, weight=1, assembly=5, model=7 id=8 partno=ENG088 description=Cylinder head price=55 2. document=9, weight=1, assembly=5, model=3 id=9 partno=ENG976 description=Large cylinder head price=65 words: 1. 'eng': 2 documents, 2 hits contentnbsp;/usr/local/bin/search --config /usr/local/etc/sphinx.conf wind Sphinx 0.9.7 Copyright (c) 2001-2007, Andrew Aksyonoff index 'catalog': query 'wind ': returned 2 matches of 2 total in 0.000 sec displaying matches: 1. document=1, weight=1, assembly=3, model=1 id=1 partno=WIN408 description=Portal window price=423 2. document=5, weight=1, assembly=3, model=1 id=5 partno=WIN958 description=Windshield, front price=500 words: 1. 'wind': 2 documents, 2 hits contentnbsp;/usr/local/bin/search \ --config /usr/local/etc/sphinx.conf --filter model 3 ENG Sphinx 0.9.7 Copyright (c) 2001-2007, Andrew Aksyonoff index 'catalog': query 'ENG ': returned 1 matches of 1 total in 0.000 sec displaying matches: 1. document=9, weight=1, assembly=5, model=3 id=9 partno=ENG976 description=Large cylinder head price=65 words: 1. 'eng': 2 documents, 2 hits
⑴条命令 /usr/local/bin/search --config /usr/local/etc/sphinx.conf ENG 在零件号中找到了两个含有 ENG 的结果。第二条命令/usr/local/bin/search --config /usr/local/etc/sphinx.conf wind 在两个零件描述中找到了子字符串 wind。而第三条命令把结果限定为 model 为 3 的条目。
回页首
最后,您可以编写 PHP 代码来调用 Sphinx 搜索引擎。Sphinx PHP API 非常小并且易于掌握。清单 12 是一个小型 PHP 应用程序,用于调用 searchd 以得到使用上面所示的最后一条命令得到的相同结果(“在属于型号 3 的名称中找到含有 ‘cylinder’ 的所有零件”)。
要测试代码,需要为 Sphinx 创建 log 目录,启动 searchd,然后运行 PHP 应用程序,如下所示:
contentnbsp;sudo mkdir -p /var/log/searchd contentnbsp;sudo /usr/local/bin/searchd --config /usr/local/etc/sphinx.conf contentnbsp;php search.php 9 Array ( [fields] => Array ( [0] => partno [1] => description ) [attrs] => Array ( [assembly] => 1 [model] => 1 ) [matches] => Array ( [9] => Array ( [weight] => 1 [attrs] => Array ( [assembly] => 5 [model] => 3 ) ) ) [total] => 1 [total_found] => 1 [time] => 0.000 [words] => Array ( [cylind] => Array ( [docs] => 2 [hits] => 2 ) ) )
输出为 9:匹配的单行的正确主键。如果 Sphinx 找到匹配,相关数组 $result 将包含名为 results 的元素。浏览 print_r() 的输出以查看返回的其他内容。
注意事项:total_found 是在索引中找到的匹配总数,而 found 是返回的结果数。这两者可能不同,因为您可以更改每次返回多少个匹配结果以及要返回哪批匹配结果,哪个结果利于对冗长的结果列表分页。请查看 API 调用 SetLimits()。一个分页示例是用 $cl->SetLimits( ( $page - 1 ) * SPAN, SPAN ) 调用搜索引擎返回⑴批、第二批、第三批(依此类推)SPAN 匹配结果,这取决于显示哪个页面。
回页首
Sphinx 还有更多的功能可以利用。我在这里仅仅介绍了最浅显的一部分,但是您现在有一个可以工作的现实示例作为基石来扩展您的技能。
仔细研读随发行版附带的样例 Sphinx 配置文件 /usr/local/etc/sphinx.conf.dist。该文件中的注释将说明每个 Sphinx 参数可以实现的功能;展示如何创建分布式冗余配置;并说明如何继承基本设置以避免源代码及索引中的重复。Sphinx README 文件还是十分丰富的信息源,包括如何将 Sphinx 直接嵌入 MySQL V5 —— 不需要使用守护程序。
加拿大旅游签证5个月都没有结果怎? 要是加拿大签证迟迟不出结果有可能需要申请人补充某些材料或者因为一些材料使馆需要审核导致时间加长,还有一种可能就是使馆有可能忘记处理你的签证。 所以说签证结果迟迟不出肯定是有原因的。最有效的办法还是重新递交一份申请。根据你的条件的复杂程度背景调查时间会变得很长,一般来讲只要没有结果,仍旧在背景调查的情况下是不会给你拒签的,但是呢,同样的就是你觉得自己的事情没什么问...
网站建设好上线后的维护方法 以往虎网网络的小编已跟大家阐明怎样设置关键词,被搜索引擎收录等。今日跟大家分享的是:新网站建设好上线后应该怎样维护? 一:检测关键词密度与做好内链 新网站建设好上线后,我们接手网站时,可以检测一下站内的关键词密度。毕竟建站企业的程序人员只是负责建好一个网站,并不将网站的关键词设置的有多好。并且关键词既不能太少也不能太多,其密度应维持在2%-8%左右。另一方面,也要做好网站内链,利于百度蜘蛛...
深圳福田瑞丰空调设备跟虎网站签下网站建设合约 瑞丰选用虎网站定制型网站案例,此类网站主要是按客户要求和提供的风格案例或效果图纸来做,这种属于仿制和定制型网站,是根据功能开发的难易度来评估报价的,价格相对较高,适合于大中型企业和有个性风格、个性功能需求的客户选用。瑞丰是经深圳市福田区工商局审核的正规企业,统一社会信用代码:0000。同时经国家工信部和广东省通信管理局审核通过ICP备案;备案号:粤ICP备10069525号。瑞丰位于深圳市福田区天...
关注网站在建设过程的各种细节 细节是魔鬼,是一本书的名字,相信很多人都看过,很多初入社会,或者是刚做销售的人,都会被推荐去看这本书,这本书里面讲了很多为人处世、礼仪仪表的细节,到现在为止,这本书给我的获益还是很大。 网站建设同样也是这样,体现一个专业网站建设公司的水平,其中有关键的一点就是对于细节的把握和关注,在虎网科技(西安网站建设),我们的项目经理和我们的设计师们,是非常关注网站的细节,在屏幕上差一个像数,好像是没太大...
地方垂直网站的生存思路 团购站、分类信息、招聘、论坛、社区等细分行业,都会存在全局和局部竞争问题。记得当年,在几大门户论坛发力的时候,地方论坛死了一大批,而类似19楼之类的一批网站却生存了下来,并且不断地转型谋求发展。这说明一个问题,找准切入点并制造差异化,地方网站建设并不是毫无胜算。 全国性的巨头网站拿到不菲的融资,各个都有想通吃全国的气魄。而地方网站精耕细作,努力维护自己的地盘。 较近与某省知名招聘网创始团...
企业制作网站应从怎样的角度去开展 企业制作网站是一项综合的工作,在进行制作网站时候,要从客户的角度来思考自己的网站,注意用户体验,一些方面是影响客户访问体验的,在制作网站的时候可以多多的思考,那企业制作网站应从怎样的角度去开展呢? 企业制作网站应从怎样的角度去开展 面临的是用户,客户体验好,有助于成交并成为忠实用户。作为制作网站,主要目的是为了成交转化,因此不管是在制作的视觉效果、产品展示布局、还是响应速度,要站在用户的角度看...
粤ICP备2023033431号 网站地图 SiteMap
Copyright 2006-2023 虎网站 版权所有